題目:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 31232 | Accepted: 9621 |
Description
Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:
1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.
2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.
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. 傳送門:點擊打開鏈接
解題思路:
分組並查集(種類並查集).建立兩個集合A和B,A中存放和元素a在同一個幫派的元素,B中存放和元素a在不同幫派(一共兩個幫派)的元素。對於'D'操作,我們只需把a和b+n放到一個集合,a+n和b放到一個集合即可,因爲a和b不在一個幫派,所以a和b+n在一個幫派,同理,a+n和b在一個幫派。對於‘A’操作,我們先判斷a和b是否在同一個幫派,即看a和b或者a+n和b+n是否在同一個集合,再看兩個元素是否在不同幫派,即看a+n和b或者a和b+n是否在同一個集合,剩下的情況是不確定。
代碼:
#include <cstdio>
#include <cstring>
const int MAXN = 1e5 + 10;
int set[MAXN<<1];
int find(int p)
{
if(set[p] < 0) return p;
return set[p] = find(set[p]);
}
void join(int p, int q)
{
p = find(p), q = find(q);
if(p != q) set[p] = q;
}
int main()
{
int t, n, m;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
memset(set, -1, sizeof(set));
while(m--)
{
char s[2];
int a, b;
scanf("%s%d%d", s, &a, &b);
switch(s[0])
{
case 'D':
{
join(a, b+n);
join(b, a+n);
break;
}
case 'A':
{
if(find(a)==find(b) || find(a+n)==find(b+n))
{
printf("In the same gang.\n");
}
else if(find(a)==find(b+n) || find(a+n)==find(b))
{
printf("In different gangs.\n");
}
else
{
printf("Not sure yet.\n");
}
break;
}
}
}
}
}