这道题是我ac的比较难的一道了,其中不仅要记录自己的父节点,还要用一个数组来记录父节点对应的异性父节点(怎么就这么拗口呢...),在将父节点的异性进行与该节点的异性的父节点进行合并(更拗口...)
具体看代码~~
- #include <stdio.h>
- #include <memory.h>
- int parent[2001];
- int aparent[2001];
- int FindParent(int a) {
- while( a != parent[a])
- a = parent[a];
- return a;
- }
- //同性间的集合合并
- int MergeSet(int a,int b)
- {
- if( a > b)
- return(parent[b] = a);
- else
- return(parent[a] = b);
- }
- //将不同性别的集合进行分类合并
- //就是让x 和 y的异性 的集合进行合并
- int MergeOppisiteSet(int a,int b)
- {
- bool flag = true;
- int t1 = FindParent(a);
- int t2 = FindParent(b);
- //如果(a和b同性) 或 (a的异性 和 b的异性 同性)则出现悖论
- if( t1 == t2 || (aparent[t1] && aparent[t2] && aparent[t1] == aparent[t2]))
- return 0;
- if( aparent[t1] != t2)
- aparent[t1] = MergeSet(aparent[t1],t2);
- if( aparent[t2] != t1)
- aparent[t2] = MergeSet(aparent[t2],t1);
- return 1;
- }
- int main()
- {
- int time,n,d;
- int x,y;
- scanf("%d",&time);
- for( int i = 1; i <= time; i++) {
- bool flag = true;
- scanf("%d%d",&n,&d);
- memset(aparent,0,(n + 1) * sizeof( int ));
- for( int j = 1; j <= n; j++)
- parent[j] = j;
- for( int j = 0 ; j < d; j++) {
- scanf("%d%d",&x,&y);
- //对每一对异性进行 分类合并
- if(!MergeOppisiteSet(x,y))
- flag = false;
- }
- if( flag )
- printf("Scenario #%d:/nNo suspicious bugs found!/n/n",i);
- else
- printf("Scenario #%d:/nSuspicious bugs found!/n/n",i);
- }
- }
这道题后我要把食物链给ac了!