题目传送门:http://poj.org/problem?id=1182
这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃;
所以可以用0,1,2三个数字代表三种情况,在使用并查集的时候再多加一个关系数组,初始时全部赋值为0
然后就是在进行并查集的每一步时加入关系的改变,
如果祖先节点相同,说明两者之间的关系已经出现,是已知的,判断两者关系之和与给的d-1是否相同
祖先节点不同,说明在此之前两者的关系还未知,就赋予关系
噢 对了 poj 上的这题要单组输入,多组会wa
code
1 #include<cstdio> 2 using namespace std; 3 int father[50005]; 4 int relat[50005]; 5 void give (int n) 6 { 7 for (int i=1;i<=n;i++) 8 { 9 father[i]=i; 10 relat[i]=0; //初始关系都为0 11 } 12 } 13 int find(int x) 14 { 15 if (x==father[x]) return father[x]; 16 int t=find(father[x]); 17 relat[x]=(relat[x]+relat[father[x]])%3; //在寻找祖先节点的过程中也要更新关系 18 father[x]=t; 19 return father[x]; 20 } 21 int main() 22 { 23 int n,k,sum,d,x,y,sx,sy; 24 scanf("%d %d",&n,&k); 25 give(n); 26 sum=0; 27 while (k--) 28 { 29 scanf("%d %d %d",&d,&x,&y); 30 if (x>n||y>n) 31 { 32 sum++; 33 continue; 34 } 35 if (d==2&&x==y) //不能自己吃自己啊 36 { 37 sum++; 38 continue; 39 } 40 sx=find(x); 41 sy=find(y); 42 if (sx==sy) //说明关系可以确定,因为在之前出现过 43 { 44 if ((relat[x]-relat[y]+3)%3!=d-1) //加三为了避免负数 45 sum++; 46 } 47 else //关系还不确定,那么不能判断,只能赋予关系 48 { 49 father[sx]=sy; 50 relat[sx]=(relat[y]-relat[x]+3+d-1)%3; //sx,sy,x,y的顺序不要反了,这都是对应的 51 } 52 } 53 printf("%d\n",sum); 54 return 0; 55 }