Submission #1193440

#TimeUsernameProblemLanguageResultExecution timeMemory
1193440loomRelay Marathon (NOI20_relaymarathon)C++20
100 / 100
1669 ms481512 KiB
#include<bits/stdc++.h>
#define int long long
#define nl endl
using namespace std;
int n;

tuple<int,int,int> MultiDijkstra(vector<pair<int,int> > graph[], vector<int> spec, vector<tuple<int,int,int> > el){
    vector<int> dist(n+1, 1e18);
    vector<int> head(n+1, -1);
    vector<int> vis(n+1, 0);
    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int> >, greater<tuple<int,int,int> > > pq;
    for(int i=0; i<spec.size(); i++){
        pq.push({0, spec[i], spec[i]});
        dist[spec[i]] = 0;
        head[spec[i]] = spec[i];
    }

    while(!pq.empty()){
        auto [d, v, h] = pq.top();
        pq.pop();

        if(vis[v]) continue;
        vis[v] = 1;

        for(auto [ch, wt] : graph[v]){
            if(d + wt < dist[ch]){
                head[ch] = h;
                dist[ch] = d + wt;
                pq.push({dist[ch], ch, head[ch]});
            }
        }
    }

    int ans = 1e18, n1, n2;
    for(int i=0; i<el.size(); i++){
        auto [u, v, wt] = el[i];
        if(head[u] != head[v]){
            if(dist[u] + wt + dist[v] < ans){
                ans = dist[u] + wt + dist[v];
                n1 = head[u], n2 = head[v];
            }
        }
    }

    return {n1, n2, ans};
}

tuple<int,int,int,int> Dijkstra(vector<pair<int,int> > graph[], vector<int> spec, int src){
    vector<int> dist(n+1, 1e18);
    vector<int> vis(n+1, 0);
    priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > pq;
    pq.push({0, src});
    dist[src] = 0;

    while(!pq.empty()){
        auto [d, v] = pq.top();
        pq.pop();

        if(vis[v]) continue;
        vis[v] = 1;

        for(auto [ch, wt] : graph[v]){
            if(d + wt < dist[ch]){
                dist[ch] = d + wt;
                pq.push({dist[ch], ch});
            }
        }
    }

    vector<pair<int,int> > v;
    for(int i=0; i<spec.size(); i++){
        v.push_back({dist[spec[i]], spec[i]});
    }
    sort(v.begin(), v.end());
    
    return {v[0].second, v[0].first, v[1].second, v[1].first};
}

signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);cout.tie(NULL);

    int m, k;
    cin>>n>>m>>k;
    vector<pair<int,int> > graph[n+1];
    vector<tuple<int,int,int> > el(m);
    for(int i=0; i<m; i++){
        int a, b, c;
        cin>>a>>b>>c;
        graph[a].push_back({b, c});
        graph[b].push_back({a, c});
        el[i] = {a, b, c};
    }
    vector<int> spec(k);
    for(int i=0; i<k; i++) cin>>spec[i];

    auto [u, v, mini] = MultiDijkstra(graph, spec, el);

    vector<pair<int,int> > graph2[n+1];
    for(int i=1; i<=n; i++){
        for(auto x : graph[i]){
            if(x.first != u and x.first != v) graph2[i].push_back(x);
        }
    }
    vector<int> spec2;
    for(int i=0; i<k; i++){
        if(spec[i] != u and spec[i] != v) spec2.push_back(spec[i]);
    }
    vector<tuple<int,int,int> > el2;
    for(int i=0; i<m; i++){
        auto [x, y, wt] = el[i];
        if(x != u and x != v and y != u and y != v) el2.push_back(el[i]);
    }

    auto [u2, v2, mini2] = MultiDijkstra(graph2, spec2, el2);

    int ans = mini + mini2;

    auto [s1, d1, s2, d2] = Dijkstra(graph, spec2, u);
    auto [s3, d3, s4, d4] = Dijkstra(graph, spec2, v);

    if(s3 != s1){
        ans = min(ans, d1 + d3);
    }else{
        ans = min(ans, min(d1 + d4, d2 + d3));
    }
    
    //cout<<s1<<" "<<d1<<nl<<s2<<" "<<d2<<nl<<s3<<" "<<d3<<nl<<s4<<" "<<d4<<nl<<mini<<" "<<mini2<<nl;
    cout<<ans;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...