并查集,向量偏移再来一发。
这个题就比上次那个食物链的要简单了。
跟龙帮虎帮的那个是一样的。
题目意思好变态:告诉两个虫子是异性,告诉你跟多的节点的信息,问你有没有同性恋的一对虫子。
/*
两种情况的向量偏移的题目。
*/
#include<iostream>
#include<stdio.h>
using namespace std;
const int N = 2010;
int father[N];
int rank[N];
void InitSet(int n)
{
for(int i = 1 ; i <= n ; i++)
{
father[i] = i;
rank[i] = 0;
}
}
int FindSet(int n)
{
if(n != father[n])
{
int t = father[n];
father[n] = FindSet(father[n]);
rank[n] = (rank[t] + rank[n])%2;/*路径压缩,更新rank[i],沿着父节点到祖先节点的路径*/
}
return father[n];
}
void UnionSet(int a,int b,int d)
{
int x = FindSet(a);
int y = FindSet(b);
father[x] = y;
rank[x] = (rank[a] - rank[b] + 2 + d)%2;/*合并向量化简更新rank[]数组*/
}
int main()
{
int ncase;
scanf("%d",&ncase);
int cnt = 0;
while(ncase--)
{
cnt++;
int n,m;
scanf("%d %d",&n,&m);
InitSet(n);
bool flag = false;
for(int i = 0 ; i < m ; i++)
{
int a,b;
scanf("%d %d",&a,&b);
int x = FindSet(a);
int y = FindSet(b);
if(x == y)
{
if(rank[a] == rank[b])
{
flag = true;
}//不能跳出,会造成终止文件输入!!
}
else
{
UnionSet(a,b,1);
}
}
printf("Scenario #%d:\n",cnt);
if(flag)
{
printf("Suspicious bugs found!\n");
}
else
{
printf("No suspicious bugs found!\n");
}
printf("\n");
}
return 0;
}