题目大意是有两个gangs,每次给你两个来自不同gangs的人,然后再问你任两个人的gangs关系。
解题思路是:将数据的最大范围扩大两倍,a 与 b 来自不同的gans,则a 与 b +n 来自相同的gangs,b 与 a+n来自相同的gangs.
判断相同gangs的条件是:findfather(a) == findfather(b);
判断不相同gangs的条件是: findfather(a) == findfather(b+n) || findfather(b) == findfather(a+n);
不确定关系的条件是:findfather(a) != findfather(b) && findfather(a)!=findfather(b+n) ;
代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100000+100;
int Set[2 * maxn] ;
int n , m ;
int t , fx , fy;
void init()
{
for(int i = 0; i < 2 * maxn ; i ++){
Set[i] = i ;
}
}
int findfather(int x)
{
if(x == Set[x]) return x ;
return Set[x] = findfather(Set[x]) ;
}
void union_ab(int x , int y)
{
int fx = findfather(x) ;
int fy = findfather(y) ;
if(fx != fy) Set[fx] = fy ;
}
int main()
{
int a , b ;
char c[3] ;
scanf("%d",&t);
while(t --){
init();
scanf("%d%d",&n , &m);
for(int i = 0; i < m; i ++){
scanf("%s%d%d",c,&a,&b);
if(c[0] =='D') {
union_ab(a , b + n);
union_ab(a + n , b);
}
else
{
if(findfather(a) == findfather(b))
printf("In the same gang.\n");
else if(findfather(a) == findfather(b+n) || findfather(a) == findfather(b))
printf("In different gangs.\n");
else
if(findfather(a+n)!=findfather(b) && findfather(b) != findfather(a))
printf("Not sure yet.\n");
}
}
}
return 0;
}
方法二:
#include <iostream> #include <cstdio> using namespace std; const int maxn = 100005; typedef struct{ int root, relation; }gang; gang data[maxn]; int t , n , m ; void init() { for(int i = 0; i < maxn; i ++) { data[i].root = i; data[i].relation = 0; } } int findfather(int x) { if(x == data[x].root) return x; int t = findfather(data[x].root); data[x].relation = (data[x].relation + data[data[x].root].relation)%2; data[x].root = t; return t; } void union_ab(int x , int y ) { int fx = findfather(x); int fy = findfather(y); if(fx != fy){ if(data[x].relation == data[y].relation) { data[fx].relation = 1; data[fx].root = fy; } if(data[x].relation != data[y].relation) { data[fx].root = fy; } } } int main() { scanf("%d",&t); char c[10]; int a , b; while(t --) { init(); scanf("%d %d",&n ,&m); for(int i = 0; i < m; i ++) { scanf("%s",c); if(c[0] == 'D') { scanf("%d%d",&a,&b); union_ab(a , b); } if(c[0] == 'A'){ scanf("%d%d",&a , &b); findfather(a); findfather(b); if(data[a].root != data[b].root) printf("Not sure yet.\n"); else { if(data[a].relation == data[b].relation) printf("In the same gang.\n"); else if(data[a].relation != data[b].relation) printf("In different gangs.\n"); } } } } return 0; }