J - 天空之城
由该题走过的路不消耗时间,那么我们只需要把最短路依次加入到答案中即可。
用并查集作为查询以便在 O(1) 时间内知道这片区域是否联通
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
#define ll long long
int n ,m;
const int N = 5e3 , M = 2e5 ;
struct G{
int x, y;
ll w;
bool operator < (const G &X) const {
return w < X.w;
}
}g[M];
int fa[N];
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int main(){
while(cin >> n >> m){
for(int i = 1 ; i <= n ; i ++) fa[i] = i;
unordered_map<string,int> ID;
string a , b;
cin >> a;
int id = 0;
ll x;
for(int i = 1 ; i <= m ; i ++){
cin >> a >> b;
scanf("%lld",&x);
if(ID[a] == 0) ID[a] = ++ id;
if(ID[b] == 0) ID[b] = ++ id;
g[i] = (G){ID[a] , ID[b] ,x } ;
}
sort(g+1,g+1+m);
ll ans = 0;
for(int i = 1 ; i <= m ; i ++){
int fx = find(g[i].x) , fy = find(g[i].y);
if(fx == fy) continue;
fa[fx] = fy;
ans += g[i].w;
}
x = find(fa[1]) ;
bool f = true;
for(int i = 1 ; i <= n ; i ++){
if(find(fa[i]) != x){
puts("No!");
f = false;
break;
}
}
if(f) printf("%lld\n",ans);
}
return 0;
} 
京公网安备 11010502036488号