hdu3038
hdu3038
带权并查集这种问题不仅仅要处理不同的点的是否在同一个集合里之类的问题,点与点之间存在连线,其带有权值,在路径压缩的时候也要对权值进行操作
这道题就是带权并查集+向量去做
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cmath> 6 #include<ctime> 7 #include<set> 8 #include<map> 9 #include<stack> 10 #include<cstring> 11 #define inf 2147483647 12 #define ls rt<<1 13 #define rs rt<<1|1 14 #define lson ls,nl,mid,l,r 15 #define rson rs,mid+1,nr,l,r 16 #define N 100010 17 #define For(i,a,b) for(int i=a;i<=b;i++) 18 #define p(a) putchar(a) 19 #define g() getchar() 20 21 using namespace std; 22 int n,m; 23 int l,r,v; 24 int d[200010]; 25 int sum[200010]; 26 int ans; 27 void in(int &x){ 28 int y=1; 29 char c=g();x=0; 30 while(c<'0'||c>'9'){ 31 if(c=='-')y=-1; 32 c=g(); 33 } 34 while(c<='9'&&c>='0'){ 35 x=(x<<1)+(x<<3)+c-'0';c=g(); 36 } 37 x*=y; 38 } 39 void o(int x){ 40 if(x<0){ 41 p('-'); 42 x=-x; 43 } 44 if(x>9)o(x/10); 45 p(x%10+'0'); 46 } 47 48 int find(int x){ 49 if(x!=d[x]){ 50 int t=d[x]; 51 d[x]=find(d[x]); 52 sum[x]+=sum[t]; 53 } 54 return d[x]; 55 } 56 57 int main(){ 58 while(scanf("%d%d",&n,&m)!=EOF){ 59 For(i,0,n){ 60 sum[i]=0; 61 d[i]=i; 62 } 63 ans=0; 64 For(ii,1,m){ 65 in(l);in(r);in(v); 66 int t1=find(--l); 67 int t2=find(r); 68 if(t1!=t2){ 69 sum[t2]=v+sum[l]-sum[r]; 70 d[t2]=t1; 71 } 72 else 73 if(v!=sum[r]-sum[l]) 74 ans++; 75 } 76 o(ans);p('\n'); 77 } 78 return 0; 79 }