BZOJ1202 [HNOI2005]狡猾的商人

带权并查集水题,头一次写这东西,纯手写。。

因为n很小,所以还不用路径压缩(其实是不会

除了记录父亲节点外,还记录下距离父亲节点的距离,每次查找祖先并且求出这段距离和。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1005;
 6 int u[maxn],v[maxn],w[maxn];
 7 int fa[maxn],d[maxn];
 8 int findd(int x,int &ans)
 9 {
10     ans = 0;
11     while(x!=fa[x]){
12         ans+=d[x];
13         x = fa[x];
14     }
15     return x;
16 }
17 int main()
18 {
19   //  freopen("in.txt","r",stdin);
20     int T;scanf("%d",&T);
21     while(T--)
22     {
23         int n,m;scanf("%d%d",&n,&m);
24         for(int i = 1;i<=m;++i)scanf("%d%d%d",u+i,v+i,w+i);
25         for(int i = 0;i<=n;++i)fa[i] = i,d[i] = 0;
26         bool ok = 1;
27         for(int i = 1;i<=m;++i){
28             u[i]--;
29             int disx,disy;
30             int fx = findd(u[i],disx),fy = findd(v[i],disy);
31             if(fx==fy){
32                 if(disx-disy!=w[i]){ok = 0;break;}
33             }
34             else if(fx<fy){
35                 fa[fx] = fy;
36                 d[fx] = w[i]+disy-disx;
37             }
38             else {
39                 fa[fy] = fx;
40                 d[fy] = disx-disy-w[i];
41             }
42         }
43         if(ok)puts("true");
44         else puts("false");
45     }
46     return 0;
47 }

 

posted on 2015-08-01 00:38  round_0  阅读(127)  评论(0编辑  收藏  举报

导航