带权的并查集
View Code
1 /* 2 带权值的并查集 3 ps:对于两个不在同一个集合里面的两个元素,把父节点接在一起即可 4 */ 5 #include<stdio.h> 6 #include<string.h> 7 #include<stdlib.h> 8 #include<algorithm> 9 #include<iostream> 10 #include<queue> 11 #include<map> 12 #include<math.h> 13 using namespace std; 14 typedef long long ll; 15 //typedef __int64 int64; 16 const int maxn = 50015; 17 const int inf = 0x7fffffff; 18 const double pi=acos(-1.0); 19 const double eps = 1e-8; 20 21 int dis[ maxn ],fa[ maxn ]; 22 23 void init( int n ){ 24 for( int i=0;i<=n;i++ ){ 25 dis[ i ] = 0; 26 fa[ i ] = i; 27 } 28 return ; 29 } 30 int find( int x ){ 31 if( fa[x]==x ) return x; 32 int tmp = find( fa[x] ); 33 dis[ x ] = dis[ x ]+dis[ fa[x] ]; 34 dis[ x ] = dis[ x ]%300; 35 fa[ x ] = tmp; 36 return fa[ x ]; 37 } 38 bool unionab( int a,int b,int c ){ 39 int x = find(a); 40 int y = find(b); 41 //printf("fa[%d]=%d,fa[%d]=%d,dis[%d]=%d,dis[%d]=%d\n",a,x,b,y,a,dis[a],b,dis[b]); 42 if( x==y ){ 43 if( ((dis[b]-dis[a]+300)%300)!=c ){//b在a的后面,保证是dis[b]-dis[a] 44 //printf("test:%d %d\n",a,b); 45 return false; 46 } 47 } 48 else{ 49 dis[ y ] = dis[ a ]+c-dis[ b ]+300; 50 dis[y] %= 300; 51 fa[ y ] = x; 52 } 53 return true; 54 } 55 int main(){ 56 int n,m; 57 while( scanf("%d%d",&n,&m)==2 ){ 58 int a,b,c; 59 init( n ); 60 int res = 0; 61 while( m-- ){ 62 scanf("%d%d%d",&a,&b,&c); 63 bool f = unionab( a,b,c ); 64 if( f==false ) res++; 65 } 66 printf("%d\n",res); 67 } 68 return 0; 69 }