UVA10158 War
Luogu 链接
UVA 链接
Virtual Judge 链接
题意
题目描述
现在有 \(n\)(\(1\le n<10^4\))个人,他们之间的关系只能是朋友或敌人,并且满足:
- 朋友的朋友是朋友。
- 敌人的敌人是朋友。
- 朋友的敌人是敌人。
- 敌人的朋友是敌人。
在开始时,每个人之间的关系是未知的。
现在给出一些操作,每个操作都形如
op x y,这些操作具体如下:
- \(op=1\):指定 \(x\) 和 \(y\) 是朋友。
- \(op=2\):指定 \(x\) 和 \(y\) 是敌人。
- \(op=3\):查询 \(x\) 和 \(y\) 是否是朋友。
- \(op=4\):查询 \(x\) 和 \(y\) 是否是敌人。
对于操作 \(1\) 和 \(2\),若该操作与之前的操作矛盾,则输出 \(-1\)。
对于操作 \(3\) 和 \(4\),若满足条件,则输出 \(1\);否则输出 \(0\)。
输入格式
第一行一个正整数 \(n\)(\(1\le n<10^4\)),含意见题目描述。
接下来若干行,每行三个正整数 \(op\)、\(x\)、\(y\),含意见题目描述。
最后一行为0 0 0,代表输入结束。
输出格式
见题目描述。
思路
考虑对于一个人 \(x\),给他设置一个假想的敌人,编号为 \(x+n\),则判断 \(x\) 与 \(y\) 是否是敌人,只需判断 \(x\) 与 \(y+n\) 或 \(x+n\) 与 \(y\) 是否是朋友即可。
对于操作 \(1\),若 \(x\) 和 \(y\) 原先就是敌人,则出现矛盾;
对于操作 \(2\),若 \(x\) 和 \(y\) 原先就是朋友,则出现矛盾。
然后就可以用并查集维护了。
程序
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<iomanip>
#include<string>
#include<stack>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define ls rt<<1
#define rs rt<<1|1
#define lb(x) (x&-x)
#define pb push_back
using namespace std;
const int N=1e4+10;
//#define use_file
//#define more_test
//#define need_init
#ifdef more_test
int T;
#endif
int fa[N<<1];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void merge(int x,int y){int fx=find(x),fy=find(y);if(fx!=fy)fa[fx]=fy;}
int n,op,x,y;
void SOLVE(/*int test_id*/){
scanf("%d",&n);
for(int i=1;i<=n<<1;++i)fa[i]=i;
while(scanf("%d%d%d",&op,&x,&y),op){
if(op==1){
if(find(x)==find(y+n)||find(y)==find(x+n))printf("-1\n");
else merge(x,y),merge(x+n,y+n);
}
if(op==2){
if(find(x)==find(y)||find(x+n)==find(y+n))printf("-1\n");
else merge(x,y+n),merge(y,x+n);
}
if(op==3){
if(find(x)==find(y)||find(x+n)==find(y+n))printf("1\n");
else printf("0\n");
}
if(op==4){
if(find(x)==find(y+n)||find(y)==find(x+n))printf("1\n");
else printf("0\n");
}
}
}
int main(){
#ifdef use_file
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
#ifdef need_init
init();
#endif
#ifdef more_test
scanf("%d",&T);
for(int i=1;i<=T;++i)SOLVE(/*i*/);
#else
SOLVE();
#endif
return 0;
}

浙公网安备 33010602011771号