POJ3723 Conscription
http://poj.org/problem?id=3723
这题虽然简单,但是还是错了很多次。
因为这题构建的图可能是不连通的。也就是说可能有很多棵树。
所以我以前写的并查集用在这上面会出问题的。
while(x != f[x])
x = f[x];
return f[x];
//我这样子每次用完之后并没有更新f[x]的值。
//虽然在连通图中没问题,但是在不连通的图里用就会有问题啦。 血的教训。。。。
改正:
if(x !=f[x])
f[x] = find(f[x]);
return f[x];
//============================================
code:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 20050; const int maxm = 50050; struct edge { int x, y, w; bool operator < (const edge& rhs) const { return w > rhs.w; } }; edge es[maxm]; int f[maxn]; int n, m; int Find(int x) { if(x !=f[x]) f[x] = Find(f[x]); return f[x]; } int kruskal() { int i, a, b; int ans = 10000*n; for(i=0; i<=n; ++i) f[i] = i; sort(es, es+m); for(i=0; i<m; ++i) { a = Find(es[i].x); b = Find(es[i].y); if(a!=b) { f[a] = b; ans -= es[i].w; } } return ans; } int main() { int N, M, R, i, t; scanf("%d",&t); while(t--) { scanf("%d%d%d",&N,&M,&R); n = N+M; m = R; for(i=0; i<m; ++i) { scanf("%d%d%d",&es[i].x, &es[i].y, &es[i].w); es[i].y += N; } printf("%d\n", kruskal()); } return 0; }