POJ3723 Conscription

时间:2023-03-08 15:34:46
POJ3723 Conscription

http://poj.org/problem?id=3723

这题虽然简单,但是还是错了很多次。

因为这题构建的图可能是不连通的。也就是说可能有很多棵树。

所以我以前写的并查集用在这上面会出问题的。

while(x != f[x])

x = f[x];

return f[x];

//我这样子每次用完之后并没有更新f[x]的值。

//虽然在连通图中没问题,但是在不连通的图里用就会有问题啦。POJ3723 Conscription 血的教训。。。。

改正:

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;
}