poj2492 + 并查集

3 篇文章 0 订阅
1 篇文章 0 订阅

题目链接:http://poj.org/problem?id=2492

题目大意:每组测试数据给出n个虫子和m种交配组合,判断虫子中有没有同性交配的。

解决方案:首先大方向确定用并查集,每个虫子都初始化为一个集合。输入交配组合是,对每队虫子先判断他们是否在一个集合,如不在,则合并集合,若在,判断他们是否同性。判断方法为与祖先进行比较。

虽然思路很清楚,但要实现的好也不容易,花了一些时间去看别人的代码,然后才明白怎么实现才更好。

#include<stdio.h>
#include<stdlib.h>
#define Max 2001
int parent[Max];
int relations[Max];     //与父亲的关系,0代表同性
void Init(int n)
{
    int i;
    for(i = 0;i <= n;i ++){
        parent[i] = i;
        relations[i] = 0;     
    }
    return;
}
int findSet(int x)
{
    int temp = parent[x];
    if(temp == x)
        return x;
    parent[x] = findSet(temp);
    relations[x] = (relations[x] + relations[temp]) % 2;  //由于之前可能已经发生了集合合并,祖先发生变动,所以要重新更新关系数组。对2取余后就可以代表与祖先的关系。
    return parent[x];
}

void unionSet(int a, int b)
{
    int root1 = findSet(a);
    int root2 = findSet(b);
    parent[root1] = root2;
    relations[root1] = (relations[a]-relations[b] + 1)%2;
}
int main(void)
{
    int i,t,n,m,a,b,flag,count;
    scanf("%d",&t);
    Init(Max - 1);
    count = 1;
    while(t --)
    {
        flag = 1;
        scanf("%d %d",&n,&m);
        for(i = 1;i <= m;i ++){
            scanf("%d %d",&a,&b);
            if(findSet(a) == findSet(b))
            {
                if(relations[a] != (relations[b] + 1) % 2)  //如果不满足异性关系,有矛盾
                    flag = 0;
            }
            else
            {
                unionSet(a, b);
            }
        }
        if(flag)
        {
            printf("Scenario #%d:\nNo suspicious bugs found!\n\n", count++);
        }
        else
        {
            printf("Scenario #%d:\nSuspicious bugs found!\n\n", count++);
        }
        Init(n);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值