http://poj.org/problem?id=2492(poj 2492 点击打开题目链接)
思路:不同类的合并树,更新关系。
分析:和poj1703很类似,都是“食物链”的简化版,这个题没出来的原因还是没理解透。如果属于同一颗树,说明可以判断两者之间的关系,但是不能说明是同性,只有既属于同一棵树,又关系相同,才能说明是同性,在输入的过程中就可以判断了,而不需要把所有的都存下来再遍历判断(但是这里不是很懂啊)。
注意:这种输入的两个是不同类的,感觉可以套模板了。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
const int maxn = 2000 + 10;
int father[maxn];
int rank[maxn];
int n,m;
void init()
{
for(int i = 0; i <= n; i++)
{
father[i] = i;
}
memset(rank,0,sizeof(rank));
}
int find(int x)
{
if(x == father[x])
return x;
//这个地方注意,自己写的时候没写出来
int y = father[x];//y是x的父亲,y是父节点,不是根节点
father[x] = find(y);
rank[x] = (rank[x] + rank[y]) % 2;//这里可以记住,以后直接用
return father[x];
}
void unin(int a,int b)
{
int fa = find(a);
int fb = find(b);
father[fa] = fb;
//记住直接用
rank[fa] = (rank[a] + 1 + rank[b]) % 2;
}
int main()
{
int t,a,b,ans = 0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
bool isok = true;
while(m--)
{
scanf("%d%d",&a,&b);
if(find(a) == find(b))
{//属于同一颗树,并且关系相同
if(rank[a] == rank[b])
{
isok = false;
}
}
else if(find(a) != find(b))
{
unin(a,b);
}
}
printf("Scenario #%d:\n",++ans);
if(!isok)
printf("Suspicious bugs found!\n");
else
printf("No suspicious bugs found!\n");
if(t)
printf("\n");
}
}
- 所有的都要处理,但是在处理过程中就可以判断是否存在关系相同的