POJ 1182
把一个点拆成x,x+n,x+2*n,x吃y可以表示认为x,y+n是一类的,x+n,y+2*n是一类,x+2*n,y是一类。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 3 const int Maxn=50100; 4 int F[Maxn*3],n,k,Type,x,y,Ans; 5 int Get(int x) {return F[x]==x?x:F[x]=Get(F[x]);} 6 int main() 7 { 8 scanf("%d%d",&n,&k); 9 for (int i=1;i<=3*n;i++) F[i]=i; 10 for (int i=1;i<=k;i++) 11 { 12 scanf("%d%d%d",&Type,&x,&y); 13 if (x>n || y>n || (x==y && Type==2)) 14 { 15 Ans++; 16 continue; 17 } 18 19 if (Type==1) 20 { 21 if (Get(x)==Get(y+n) || Get(x)==Get(y+2*n)) 22 { 23 Ans++; 24 continue; 25 } 26 F[Get(x)]=Get(y); 27 F[Get(x+n)]=Get(y+n); 28 F[Get(x+2*n)]=Get(y+2*n); 29 } else 30 { 31 if (Get(x)==Get(y) || Get(x)==Get(y+2*n)) 32 { 33 Ans++; 34 continue; 35 } 36 F[Get(x)]=Get(y+n); 37 F[Get(x+n)]=Get(y+2*n); 38 F[Get(x+2*n)]=Get(y); 39 } 40 } 41 printf("%d\n",Ans); 42 return 0; 43 }
HDU 3047
Sum[x]表示fa[x]和x的差. 带权并查集
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> int Sum[50010],Father[50010],n,m,Count,u,v,w; int Get_Father(int x) { if (x==Father[x]) return x; int Tmp=Get_Father(Father[x]); Sum[x]+=Sum[Father[x]]; return Father[x]=Tmp; } int main() { while (scanf("%d%d",&n,&m)!=EOF) { for (int i=0;i<=n;i++) Father[i]=i,Sum[i]=0; Count=0; for (int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); int fu=Get_Father(u),fv=Get_Father(v); if (fu!=fv) { Father[fu]=fv; Sum[fu]=Sum[v]+w-Sum[u]; } else { if (Sum[u]-Sum[v]!=w) Count++; } } printf("%d\n",Count); } return 0; }
BZOJ 1202
带权并查集
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 int KASE,n,m,u,v,w; 3 int Father[20010],Sum[20010]; 4 int Get_Father(int x) 5 { 6 if (x==Father[x]) return x; 7 int Tmp=Get_Father(Father[x]); 8 Sum[x]+=Sum[Father[x]]; 9 Father[x]=Tmp; 10 return Tmp; 11 } 12 int main() 13 { 14 scanf("%d",&KASE); 15 for (int Kase=1;Kase<=KASE;Kase++) 16 { 17 scanf("%d%d",&n,&m); bool flag=false; 18 for (int i=0;i<=n;i++) Father[i]=i,Sum[i]=0; 19 for (int i=1;i<=m;i++) 20 { 21 scanf("%d%d%d",&u,&v,&w); 22 int fu=Get_Father(u-1),fv=Get_Father(v); 23 if (fu==fv) 24 { 25 if (Sum[u-1]-Sum[v]!=w) 26 { 27 flag=true; 28 break; 29 } 30 } else 31 { 32 Father[fu]=fv; 33 Sum[fu]=Sum[v]-Sum[u-1]+w; 34 } 35 } 36 puts(flag?"false":"true"); 37 } 38 return 0; 39 }