Description
Input
Output
Sample Input
1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4
Sample Output
Not sure yet. In different gangs. In the same gang.
Source
题目大意:
解题思路:T组测试数据,n个人,m组询问,2个帮派,D a b 表示 a,b 不在同一帮派 ,A a b表示查询a和b的关系。
参考代码:并查集。将每个人对应两个节点,分属于两个帮派。1~n表示帮派1中的,n+1~2n表示帮派2中的。若知道a和b不是同一帮的,那么将a和b+n放到一个集合中,b和a+n放到一个集合中。并查集查询a和b的关系时,如果a与b+n在一个集合中,则说明他们不在同一帮;若a和b在同一集合,则在同一帮;否则说明他们关系不确定。连线时交叉连,即保证间隔两人在同一集合。即敌人的敌人是朋友。
#include <cstdio> using namespace std; const int MAXN = 200010; int N, M, nCase, father[MAXN], rank[MAXN]; int find_set(int x) { return father[x] = father[x] == x ? x : find_set(father[x]); } void union_set(int x, int y) { int a = find_set(x), b = find_set(y); if (rank[a] < rank[b]) { father[a] = b; } else { father[b] = a; if (rank[a] == rank[b]) { rank[a]++; } } } void init() { for (int i = 1; i <= 2*N; i++) { father[i] = i; rank[i] = 1; } } void solve() { for (int i = 0; i < M; i++) { char op; int a, b; getchar(); scanf("%c%d%d", &op, &a, &b); if (op == 'D') { union_set(a, b+N); union_set(b, a+N); } else if (op == 'A') { if (find_set(a) == find_set(b+N)) { printf("In different gangs.\n"); } else if (find_set(a) == find_set(b)) { printf("In the same gang.\n"); } else { printf("Not sure yet.\n"); } } } } int main() { scanf("%d", &nCase); while (nCase--) { scanf("%d%d", &N, &M); init(); solve(); } return 0; }
POJ 1703 Find them, Catch them(数据结构-并查集),布布扣,bubuko.com
POJ 1703 Find them, Catch them(数据结构-并查集)
原文地址:http://blog.csdn.net/wujysh/article/details/38358035