UVa10158 War

来源:互联网 发布:淘宝买东西怎么拿发票 编辑:程序博客网 时间:2024/05/22 22:25

        题意:有n个人,彼此间是朋友或敌对关系。有4种操作:1设置a,b为朋友 2设置a,b为敌对 3询问a,b是不是朋友 4询问a,b是不是敌对。对于询问操作,如果是输出1,否则输出0。对于设置操作,如果与已知关系矛盾,输出-1,操作无效;有效的设置不输出。

        思路:有相互关系的并查集。如果已知两个人的关系,不管是朋友还是敌对,就放到一个集合里。用一个数组表示元素与父元素间的关系。不管是查找和合并都涉及到关系数组的改变,写的时候头脑一定要清醒,了解它是怎么运作的。

#include <iostream>#include <stdio.h>#include <cmath>#include <algorithm>#include <iomanip>#include <cstdlib>#include <string>#include <memory.h>#include <vector>#include <queue>#include <stack>#include <ctype.h>#define INF 1000000using namespace std;int fa[10010];bool rel[10010];int find(int i){if(i==fa[i])return i;int t=fa[i];fa[i]=find(fa[i]);rel[i]=!(rel[i]^rel[t]);return fa[i];}void uni(int a,int b,bool f){int t=find(a);fa[find(a)]=find(b);rel[t]=!(!(rel[a]^rel[b])^f);find(a);find(b);}int main(){int n;while(cin>>n){for(int i=0;i<=n;i++){fa[i]=i;}for(int i=0;i<=n;i++){rel[i]=1;}int c,x,y;while(cin>>c>>x>>y){if(!(c||x||y))break;switch(c){case 1:if(find(x)!=find(y)){uni(x,y,true);}else if(rel[x]!=rel[y]){cout<<"-1"<<endl;}break;case 2:if(find(x)!=find(y)){uni(x,y,false);}else if(rel[x]==rel[y]){cout<<"-1"<<endl;}break;case 3:if(find(x)==find(y)){if(rel[x]==rel[y]){cout<<"1"<<endl;}else{cout<<"0"<<endl;}}else{cout<<"0"<<endl;}break;case 4:if(find(x)==find(y)){if(rel[x]==rel[y]){cout<<"0"<<endl;}else{cout<<"1"<<endl;}}else{cout<<"0"<<endl;}break;}}}return 0;} 


0 0