POJ 1703(Find them, Catch them)

題意:比較好懂,略;

思路:挺不錯的一個並查集的題,這裏需要記錄每個人的敵人,和lrj黑書上的並查集專題那題有點像,就是敵人的敵人是朋友,用個數組記錄下每個人的敵人就好了,也只需記錄其中一個敵人即可,因爲通過一個可以找到其他的,每次有更新信息D a b的時候就讓a,enemy[b]和b,enemy[a]合併,因爲他們肯定是一夥的,還要注意處理合並空集的情況;詢問時,當a,b在同一集合時,他們是一夥的,當a的敵人裏有b或b的敵人裏有a則說明他們不是一夥的,轉換成如果a和enemy[b]或b和enemy[a]是同一集合,則說明a和b不是一夥的,否則就是關係尚未確定;

#include <cstdio>
#include <cstring>
using namespace std;

const int N = 100010;
int check[N], enemy[N];

int getFather(int x){
	if(x != check[x])
		check[x] = getFather(check[x]);
	return check[x];
}

void Union(int x, int y){
	int fx = getFather(x);
	int fy = getFather(y);
	if(fx != fy)
		check[fx] = fy;
}

int main(){
	int n, m, T, a, b, i;
	scanf("%d", &T);
	while(T--){
		char ord;
		memset(enemy, 0, sizeof(enemy));
		scanf("%d%d", &n, &m);
		for(i = 1;i <= n;i++)
			check[i] = i;
		for(i = 0;i < m;i++){
			getchar();
			scanf("%c%d%d", &ord, &a, &b);
			if(ord == 'D'){
				if(enemy[a] != 0)
					Union(b, enemy[a]);
				if(enemy[b] != 0)
					Union(a, enemy[b]);
				enemy[a] = b;
				enemy[b] = a;
			} else {
				if(getFather(a) == getFather(b))
					printf("In the same gang.\n");
				else if(getFather(enemy[a]) == getFather(b))
					printf("In different gangs.\n");
				else
					printf("Not sure yet.\n"); 
			}	
		}
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章