题目链接:http://poj.org/problem?id=1182
题意:题目是中文的,就不多说了
解题思路:这个题目想了我好久,之前一直不会做。看了很多题解,但是悲催的是连有些题解都看不懂,但是吧,今天终于弄懂了。我看了《挑战程序设计竞赛》上的题解。对于一个动物,我们并不知道它属于何种生物,因而也就无法无法直观的确定她它是哪一种的。所以,我们对一个动物i创建3个元素i-A,i-B,i-C。如果x和y属于同一类,就合并 unite(x,y);unite(x+N,y+N);unite(x+2*N,y+2*N);如果,x和y是不是关系,就合并unite(x,y+N);unite(x+N,y+2*N);unite(x+2*N,y)。
#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXN=50000+10;
int p[MAXN*3],Rank[MAXN*3];
int Find(int x)
{
return p[x]==x?x:p[x]=Find(p[x]);
}
bool same(int x,int y)
{
return Find(x)==Find(y);
}
void unite(int x,int y)
{
int u=Find(x);
int v=Find(y);
if(u!=v)
{
if(Rank[u]<Rank[v])
p[u]=v;
else
{
p[v]=u;
if(Rank[v]==Rank[u])
Rank[x]++;
}
}
else
return;
}
int main()
{
int N,K;
cin>>N>>K;
for(int i=0;i<3*N;i++)
{
p[i]=i;
Rank[0]=0;
}
int ans=0;
while(K--)
{
int temp;
int x,y;
scanf("%d %d %d",&temp,&x,&y);
if(x<1||x>N||y<1||y>N)
{
ans++;
continue;
}
x--;
y--;
if(temp==1)
{
if(same(x,y+N)||same(x,y+2*N))//不能是捕食或者被捕食关系
ans++;
else
{
unite(x,y);
unite(x+N,y+N);
unite(x+2*N,y+2*N);
}
}
else
{
if(same(x,y)||same(x,y+2*N))//不能是同类或者被捕食
ans++;
else
{
unite(x,y+N);
unite(x+N,y+2*N);
unite(x+2*N,y);
}
}
}
cout<<ans<<endl;
return 0;
}