UVA 10158 War(并查集)

//思路详见课本 P 214 页

思路:直接用并查集,set [ k ]  存 k 的朋友所在集合的代表元素,set [ k + n ] 存 k  的敌人 所在集合的代表元素。


#include<iostream>
#include<cstring>
using namespace std;
const int maxn=2 *10000 +100;
int set[maxn];
int n;
int set_find(int d)
{
	if(set[d]<0)
		return d;
	return set[d]=set_find(set[d]);
}
int arefriends(int x,int y)
{
	if( ( set_find(x)!=set_find(y) ) &&( set_find(x)!=set_find(y+n) ) )         // ----------   不确定关系----- 返回 -1
		return -1;
	else if(set_find(x)==set_find(y))         // ----------   是朋友----- 返回 1
		return 1;
	return 0;        //----------  是敌人----- 返回 0
}
int areenemies(int x,int y)
{
	if(arefriends(x,y)==-1)         // ---------- 不确定关系----- 返回 -1
		return -1;
	else if(arefriends(x,y)==1)         //  ----------   是朋友-----  返回 0
		return 0;
	return 1;      // ----------  是敌人----- 返回 1
}
void setfriends(int x,int y)//----------是敌人------输出 -1


{
	if(arefriends(x,y)==0)
		cout<<-1<<endl;
	else if( arefriends(x,y)==-1 )//---当时我把括号写错了  -- -->else if( arefriends(x,y==-1) ),出现了 runtime error
	{
		set[set_find(x)]=set_find(y);
		set[set_find(x+n)]=set_find(y+n);
	}
}
void setenemies(int x,int y)
{
	if(arefriends(x,y)==1)       //---------是朋友----------输出 -1
		cout<<-1<<endl;
	else if(arefriends(x,y)==-1)
	{
		set[set_find(x+n)]=set_find(y);
		set[set_find(x)]=set_find(y+n);
	}
}
int main()
{
	memset(set,-1,sizeof(set));
	cin>>n;
	
	int c,x,y;
	while(cin>>c>>x>>y)
	{
		if(c==0 && x==0 &&y==0)
			break;
		if(c==1)
			setfriends(x,y);
		else if(c==2)
			setenemies(x,y);
		else if(c==3)
			cout<< ( arefriends(x,y)==1?1:0 ) <<endl;
		else if(c==4)
			cout<< ( areenemies(x,y)==1?1:0 ) <<endl;
	}
	return 0;
}



posted @ 2014-07-29 11:10  gongpixin  阅读(166)  评论(0编辑  收藏  举报