POJ - 1703 Find them, Catch them
题意:
警察需要将犯人分类(只有两派),D[a][b]表示a,b犯人是不同一派的,A[a][b]表示输入a,b犯人的关系,关 系有三种:1.无法确定 2.同一派 3.不同派
分析:
种类并查集 方法一:只要输入D,就将a,b两个合并,并将改他们的关系(g[px]=g[x]^g[y]^1),输入A的时候判断a,b是 否合并过,没有输出无法确定,合并过再判断是不是同一派。(代码里有注释) 方法二:将f[]大小为原来的两倍(乘倍后的数组,每一半都表示同一派的),输入D的时候x,y+n合并,x+n,y合 并,最后查询两个节点的父亲节点是不是再同一半数组里,是就是同一派,不是则不是同一派,其他情况都是无法 确定
code1:
#define debug #include<stdio.h> #include<math.h> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<functional> #include<iomanip> #include<map> #include<set> #define pb push_back #define dbg(x) cout<<#x<<" = "<<(x)<<endl; #define lson l,m,rt<<1 #define cmm(x) cout<<"("<<(x)<<")"; #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1e5; const ll INF=0x3f3f3f3f; const ll inf=0x7fffff; const int mod=1e9+7; const int MOD=10007; //---- //define int f[maxn+10]; int g[maxn+10]; //findset int findset(int x) { if(f[x]!=x) { int p=f[x]; f[x]=findset(f[x]); g[x]^=g[p]; } return f[x]; } //unite void unite(int x,int y) { int px=findset(x),py=findset(y); if(px==py)return; f[px]=py; g[px]=g[y]^g[x]^1;//更新x的父节点跟y(y的父节点)的关系 } void init(int n) { for(int i=1; i<=n; i++) { f[i]=i; g[i]=0;//0表示同派 } } //solve void solve() { int T; scanf("%d",&T); while(T--) { int n,m,x,y; char mark; scanf("%d%d",&n,&m); getchar();//一定要加 init(n); for(int i=0; i<m; i++) { scanf("%c%d%d",&mark,&x,&y); getchar();//一定要加 if(mark=='D') { unite(x,y); } else { if(findset(x)==findset(y)) puts(g[x]==g[y]?"In the same gang.":"In different gangs."); else puts("Not sure yet."); } } } } int main() { // ios_base::sync_with_stdio(0); #ifdef debug freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif // cin.tie(0); // cout.tie(0); solve(); return 0; }
code2:
#define debug #include<stdio.h> #include<math.h> #include<cmath> #include<queue> #include<stack> #include<string> #include<cstring> #include<string.h> #include<algorithm> #include<iostream> #include<vector> #include<functional> #include<iomanip> #include<map> #include<set> #define pb push_back #define dbg(x) cout<<#x<<" = "<<(x)<<endl; #define lson l,m,rt<<1 #define cmm(x) cout<<"("<<(x)<<")"; #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1e5; const ll INF=0x3f3f3f3f; const ll inf=0x7fffff; const int mod=1e9+7; const int MOD=10007; //---- //define int f[maxn+10]; int g[maxn+10]; //findset int findset(int x) { return f[x]==x?x:f[x]=findset(f[x]); } //unite void unite(int x,int y) { int px=findset(x),py=findset(y); if(px==py)return; f[px]=py; } //init void init(int n) { for(int i=1; i<=2*n; i++) { f[i]=i; } } //solve void solve() { int T; scanf("%d",&T); while(T--) { int n,m,x,y; char mark; scanf("%d%d",&n,&m); getchar();//一定要加 init(n); for(int i=0; i<m; i++) { scanf("%c%d%d",&mark,&x,&y); getchar();//一定要加 if(mark=='D') { unite(x,y+n); unite(x+n,y); } else { if(findset(x)==findset(y)||findset(x+n)==findset(y+n)){ cout<<"In the same gang.\n"; }else if(findset(x)==findset(y+n)||findset(x+n)==findset(y)){ cout<<"In different gangs.\n"; }else cout<<"Not sure yet.\n"; } } } } int main() { // ios_base::sync_with_stdio(0); #ifdef debug freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif // cin.tie(0); // cout.tie(0); solve(); return 0; }