# SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛* G题 危险路径

mst要合并两个并查集时，设它们的根为x,y

siz[x] > siz[y], 将把y的父亲设为x。

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define ul unsigned long long
#define fo(i, x, y) for(ll i = x; i <= y; i ++)
using namespace std;

const ll N = 1e6 + 5;

ll T, n, m, x, y;
ll f[N];
ll sum[N], ans, siz[N];

ll find(ll x) {return f[x] == x ? x : find(f[x]);}

struct edge {
ll x, y, z;
} e[N];

bool cmp(edge a, edge b) {
return a.z < b.z;
}

ll final[N], to[N], nxt[N], tot;

void link(ll x, ll y) {
nxt[++ tot] = final[x], to[tot] = y, final[x] = tot;
}

ll d[N];

int main() {
ll num = 1;
for(scanf("%lld", &T); T; T --, num ++) {
scanf("%lld %lld", &n, &m);
fo(i, 1, n) f[i] = i, siz[i] = 1, sum[i] = 0, final[i] = 0;
fo(i, 1, tot) nxt[i] = to[i] = 0; tot = 0;
fo(i, 1, m) scanf("%lld %lld %lld", &e[i].x, &e[i].y, &e[i].z);
sort(e + 1, e + m + 1, cmp);
fo(i, 1, m) {
ll x = e[i].x, y = e[i].y, z = e[i].z;
if(find(x) != find(y)) {
x = find(x), y = find(y);
if(siz[x] < siz[y]) swap(x, y);
sum[x] += z * siz[y];
sum[y] -= sum[x] -  z * siz[x];
f[y] = x; siz[x] += siz[y];
}
}
ll g = find(1); ul ss = 0;
d[d[0] = 1] = g;
fo(i, 1, d[0]) {
ll x = d[i]; ss ^= (ul) sum[x] * x;
for(ll j = final[x]; j; j = nxt[j])
sum[to[j]] += sum[x], d[++ d[0]] = to[j];
}
printf("Case #%lld: %llu\n", num, ss);
}
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120