papamelon 349. 城市幫派 Find them, Catch them(挑戰程序設計競賽)

地址 https://www.papamelon.com/problem/349

一個城市裏有兩個幫派,另外有 N 個成員,成員從 1∼N 進行編號,每個成員來自於其中一個幫派。
給定 M 個信息,每個信息有兩種格式:
D a b:a,b(1≤a,b≤N,a≠b) 兩個人不是一個幫派的
A a b: 判斷 a,b(1≤a,b≤N,a≠b) 兩個人是否爲同一個幫派
兩人同屬一個幫派則輸出 In the same gang.
不同屬一個幫派則輸出 In different gangs.
根據現有的消息無法確定則輸出 Not sure yet.

輸入
第一行整數 T(1≤T≤20),表示有多少組測試數據
每組測試數據格式如下:
第一行兩個整數N,M(1≤N,M≤10^5),表示成員的數量,消息的數量
接下來 M 行,每行一條消息,隨機給出,格式如上所述
輸出
對於每個 A 操作,需要一行結果,可能爲 In the same gang.,In different gangs.,Not sure yet.

輸入
1
5 5
A 1 2
D 1 2
A 1 2
D 2 4
A 1 4
輸出
Not sure yet.
In different gangs.
In the same gang.

解答 並查集
兩個幫派成員不是A就是B 不是敵對就是同夥
並查集N 表示幫派A N+1到2N表示幫派B

所以兩個成員ab 要麼a==b  要麼a==b+N  b==a+N
#include <iostream>

using namespace std;

const int N = 200020;
int f[N];
int n, m, t;

void init() {
	for (int i = 0; i < N; i++) { f[i] = i; }
}


int find(int x) {
	if (f[x] != x) { f[x] = find(f[x]); }
	return f[x];
}

void merge(int a, int b) {
	a = find(a); b = find(b);
	if (a < b) {
		f[b] = a;
	}
	else {
		f[a] = b;
	}
}


int main()
{
	scanf("%d",&t);
	while (t--) {
		init();
		scanf("%d%d",&n,&m);

		for (int i = 0; i < m; i++) {
			char op[2]; int a, b;
			scanf("%s%d%d", op, &a, &b);

			if (op[0] == 'A') {
				a = find(a); b = find(b);
				int aN = find(a + n); int bN = find(b + n);
				if (a == b) {
					printf("In the same gang.\n");
				}
				else if (a == bN || b == aN) {
					printf("In different gangs.\n");
				}
				else {
					printf("Not sure yet.\n");
				}
			}
			else {
				merge(a,b+n);
				merge(b, a + n);
			}
		}
	}

	return 0;
}

視頻題解空間

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