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 }
弱者究竟为何而战?!