http://acm.hdu.edu.cn/showproblem.php?pid=1829
题意:科学家想验证一帮虫子中是否有同性恋,已知给出n个虫子和k个性关系,想知道这帮虫子是否可疑,也就是有同性恋。
思路:又是N久没做并查集,参考这位。大致思想如下:
如果我还没有配偶,那我的配偶就是你;
如果我有配偶了,那把我的配偶和你合并为同一类。
但凡合并的节点,经过路径压缩后原本应该都是同性,若输入的发生性关系的两虫为同一集合,同性恋鉴定完毕。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 2005;
int pre[N], mate[N];
int Find(int x)
{
int r = x;
while(pre[r] != r)
r = pre[r];
int i = x, j;
while(pre[i] != r)
{
j = pre[i];
pre[i] = r;
i = pre[i];
}
return r;
}
void Union(int p1, int p2)
{
int x = Find(p1);
int y = Find(p2);
if(x != y)
{
pre[x] = y;
}
}
void init()
{
memset(mate, 0, sizeof(mate));
for(int i = 1; i <= N; i++)
pre[i] = i;
}
int main()
{
// freopen("in.txt", "r", stdin);
int t, n, k, x, y, Case = 1;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &k);
init();
int flag = 0;
for(int i = 1; i <= k; i++)
{
scanf("%d%d", &x, &y);
if(flag) continue;
if(Find(x)==Find(y))
{
flag = 1;
continue;
}
if(mate[x]==0) mate[x] = y;
else Union(mate[x], y);
if(mate[y]==0) mate[y] = x;
else Union(x, mate[y]);
}
printf("Scenario #%d:\n", Case++);
if(flag) printf("Suspicious bugs found!\n\n");
else printf("No suspicious bugs found!\n\n");
}
}