HDU 3038 How Many Answers Are Wrong
题解:用加权并查集,将小的节点作为父节点,每一次压缩路径时传递和的信息,如果已有信息存在,判断是否是正确的即可:
#include <cstdio> int n, m, data, ans; int f[200010],sum[200010]; int sf(int x){ int t; if(x==f[x])return f[x]; t=f[x]; f[x]=sf(f[x]); sum[x]+=sum[t]; return f[x]; } int Union(int x, int y){ int a, b; a=sf(x); b=sf(y); if(a==b){ if(sum[y]!=sum[x]+data) ans++; return 0; } if(a>b){ sum[a]=sum[y]-sum[x]-data; f[a]=b; } else{ sum[b]=sum[x]+data-sum[y]; f[b]=a; } return 0; } void init(){ int i; for(i=0;i<=n;i++){ f[i]=i; sum[i]=0; } } int main(){ int i, j, left, right; while(scanf("%d%d", &n, &m) != EOF){ ans = 0; init(); for(i = 0 ; i < m ; i++){ scanf("%d%d%d",&left,&right,&data); Union(left-1,right); } printf("%d\n", ans); } return 0; }
愿你出走半生,归来仍是少年