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;
}

 

posted @ 2018-06-06 21:29  visualVK  阅读(173)  评论(0编辑  收藏  举报