题意:给定n个城市,进行询问,1代表结盟,2代表敌对,3询问是否结盟,4询问是否敌对。如果有矛盾的情况输出-1,询问正确输出1失败输出0.
思路:并查集,0 - n代表结盟集合,n - 2n代表敌对集合。
#include <cstdio>
#include <math.h>
#include <cstring>
int n;
int parent[20005];
int find(int x)
{
if(x!=parent[x]) return parent[x]=find(parent[x]);
else return x;
}
int main()
{
while(scanf("%d",&n)!=EOF)//n个城市
{
int q,a,b;
for(int i=0;i<n;i++)
{
parent[i]=i; // 同盟
parent[i+n]=i+n;// 另一个同盟国
}
while(scanf("%d %d %d",&q,&a,&b)!=EOF &&q)
{
//每次输入的两个国家都单独考虑
//一个同盟国 //另一个同盟国
int a1= find(a); int a2=find(a+n);
int b1= find(b); int b2=find(b+n);
//本题 可以将 看成两边
/*
1 1
2 2
3 3
4 4
5 5
同盟,自己连起来
敌对,交叉连起来
*/
//同盟国里的一个国家 和 每一个敌对国家 敌对。
if(q==1)
{ //若已经敌对。报错
if(a1==b2) printf("-1\n");
else
{
parent[a1]=b1;//同盟,将a1和b1 连接起来
parent[a2]=b2;//同盟,将a2和b2 连接起来
}
}
else if(q==2)// 确认敌对
{ //若已经同盟。报错
if(a1==b1) printf("-1\n");
else {
parent[a1]=b2;
parent[a2]=b1;
}
}
else if(q==3)
{
if(a1==b1) printf("1\n");
else printf("0\n");
}
else if(q==4)
{
if(a1==b2) printf("1\n");
else printf("0\n");
}
}
}
return 0;
}