#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define fast() ios_base::sync_with_stdio(false); cin.tie(NULL)
const int N = 1e5+1;
const int INF = 1e6;
set<vector<int>> edges; // wt, v1, v2
vector<pair<int,int>> g[N];
vector<pair<int,int>> mst[N];
int sz[N];
int parent[N];
int level[N];
int bfsvis[N];
int ppl[N];
int dfs(int v, int p){
    int ans=ppl[v];
    for(auto node : mst[v]){
        int child = node.first;
        if(child==p) continue;
        ans+=dfs(child,v);
    }
    return ans;
}
void bfs(int src){
    queue<int> q;
    level[src]=0;
    bfsvis[src]=1;
    q.push(src);
    while(q.size()>0){
        int v = q.front();
        q.pop();
        bfsvis[v]=1;
        for(auto node : mst[v]){
            int child = node.first;
            if(bfsvis[child]) continue;
            q.push(child);
            level[child] = level[v]+1;
        } 
    }
}
bool roadexists(int v1, int v2){
    for(auto child : mst[v1]){
        int v = child.first;
        if(v==v2) return true;
    }
    return false;
}
//***********U F D S*********************
void make(int a){
    parent[a]=a;
    sz[a]=1;
}
int find(int v){
    if(v==parent[v]){
        return v;
    }
    parent[v]=find(parent[v]);
    return parent[v];
}
void Union(int a, int b){
    a=find(a);
    b=find(b);
    if(a!=b){
        if(sz[a]<sz[b]){
            swap(a,b);
        }
        parent[b]=a;
        sz[a]+=sz[b];
    }
}
//**************************8
void kruskal(int n){
    for(int i=1;i<=n;++i) make(i);
    for(int i=1;i<=n;++i){
        mst[i].clear();
    }    
    for(auto edge : edges){
        int wt = edge[0];
        int v1 = edge[1];
        int v2 = edge[2];
        if(find(v1)==find(v2)) continue;
        Union(v1,v2);
        mst[v1].pb({v2,wt});
        mst[v2].pb({v1,wt});
    }
}
signed main() {
    fast();
    int n,m,k; cin>>n>>m>>k;
    map<pair<int,int>,int> dist;
    //*************input******************
    for(int i=0;i<m;++i){
        int a,b,c; cin>>a>>b>>c;
        g[a].pb({b,c});
        g[b].pb({a,c});
        edges.insert({c,a,b});
    }
    vector<pair<int,int>> newroads;
    for(int i=0;i<k;++i){
        int x,y; cin>>x>>y;
        newroads.pb({x,y});
        edges.insert({INF,x,y});
        dist[{x,y}] = INF;
        dist[{y,x}] = INF;
    }
    for(int i=1;i<=n;++i){
        cin>>ppl[i];
    }
    //*************************************
    for(int i=0;i<k;++i){
        int v1 = newroads[i].first;
        int v2 = newroads[i].second;
        int lo = 1;
        int hi = INF;
        //BINARY SEARCH TO FIND MAX FEE ST ROAD IS INCLUDED IN MST***********
        while(hi-lo>1){
            int mid = (hi+lo)/2;
            if(edges.find({dist[{v1,v2}] , v1, v2}) != edges.end()){
                edges.erase({dist[{v1,v2}] , v1, v2});
            }
            else{
                edges.erase({dist[{v1,v2}] , v2, v1});
            }
            edges.insert({mid, v1, v2});
            dist[{v1,v2}] = mid;
            dist[{v2,v1}] = mid;
            kruskal(n);
            if(roadexists(v1,v2)){
                lo=mid;
            }
            else{
                hi=mid-1;
            }
        }
        if(edges.find({dist[{v1,v2}] , v1, v2}) != edges.end()){
                edges.erase({dist[{v1,v2}] , v1, v2});
        }
        else{
            edges.erase({dist[{v1,v2}] , v2, v1});
        }
        edges.insert({hi, v1, v2});
        dist[{v1,v2}] = hi;
        dist[{v2,v1}] = hi;
        kruskal(n);
        if(!roadexists(v1,v2)){
            edges.erase({hi,v1,v2});
            edges.insert({lo,v1,v2});
            dist[{v1,v2}]=lo;
            dist[{v2,v1}]=lo;
            kruskal(n);            
        }
        //*****************************************
    }
    //FINAL MST IS NOW READY
    //bfs on 1 to find which of the cities at endpts of
    //the k roads are furhter apart from 1
    
    bfs(1);
    int ans = 0;
    for (auto it = dist.begin(); it != dist.end(); ++it) {
        auto pr = it->first;
        int v1 = pr.first;
        int v2 = pr.second;
        // Ensure v2 is farther from town 1 than v1
        if (level[v1] > level[v2]) continue;
        // Count participants passing through the new road
        int z = dfs(v2, v1);
        //cout<<dfs(v2,v1)<<" "<<v2<<" "<<v1<<"\n";
        ans += z * dist[{v1, v2}];
    }
    cout << ans;
    
    /*
    for(int i=1;i<=n;++i){
        for(auto node : mst[i]){
            cout << "city "<<i<<" is connected with city "<<node.first<<" and has fee "<<node.second<<"\n";
        }
    }
    */
    
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |