Description
题目大意:有两个帮派,龙帮派和蛇帮派,判断两个人a和b是不是同属于一个帮派
Input
第一行T表示有T组数据
每组数据第一行为n和m,代表n个人,m次查询
每次查询分别为
A a b 意思是:查询a和b是否在一个集合
D a b 意思是:a和b不在一个集合
Output
对于每个A查询,都输出三个答案,“In the same gang.”, “In different gangs.” and “Not sure yet.”
解题思路
记住一句话,敌人的敌人就是朋友,我们把每次D操作用foe数组记录为a和b互相为敌人,同时分别与对方的敌人合并,这样就不会两个人在一个集合,对于A查询操作,如果一个人和对方的敌人在一个集合,说明他们也是敌人,所以在不同的帮派,如果两个人在同一个集合说明他们在一个帮派,除此之外便是不确定,注意:cin输入会超时
代码
//freopen("hao.txt","r",stdin);
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 100005;
int foe[N];
struct Subset
{
int parent;
int rank;
}subsets[N];
int find(int x)
{
if(subsets[x].parent!=x)
subsets[x].parent = find(subsets[x].parent);
return subsets[x].parent;
}
void Union(int x,int y)
{
int x_root = find(x);
int y_root = find(y);
if(x_root==y_root)
return;
if(subsets[x_root].rank < subsets[y_root].rank){
subsets[x_root].parent = y_root;
}
else if(subsets[x_root].rank > subsets[y_root].rank)
subsets[y_root].parent = x_root;
else {
subsets[x_root].parent = y_root;
subsets[y_root].rank++;
}
}
int main()
{
int T = 0;
int n = 0,m = 0;
char R;
int people_a = 0,people_b = 0;
freopen("hao.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
cin>>n>>m;
// 标记敌人
memset(foe,0,sizeof(foe));
for(int i=0;i<=n;i++) {
subsets[i].rank = 0;
subsets[i].parent = i;
}
for(int i=1;i<=m;i++)
{
scanf(" %c%d%d",&R,&people_a,&people_b);
//cin>>R>>people_a>>people_b;
if(R == 'A') {
// 如果和a的敌人在一个集合,说明a和b在不同的帮派
if(find(people_a) == find(foe[people_b]))
printf("In different gangs.\n");
// 如果两个人在一个集合,说明是相同的帮派
else if(find(people_a)==find(people_b))
printf("In the same gang.\n");
else
printf("Not sure yet.\n");
}
else {
if(foe[people_a])
Union(foe[people_a],people_b);
if(foe[people_b])
Union(foe[people_b],people_a);
foe[people_a] = people_b;
foe[people_b] = people_a;
}
}
}
return 0;
}