【图论05】并查集 1004 A Bug's Life

来源:互联网 发布:淘宝开放接口 编辑:程序博客网 时间:2024/06/04 18:56
  

这题除了用并查集之外,还可以DFS、BFS、二分图过!


并查集:

题意:
首先给定n只虫子,然后给出m个情况。每个情况给出两只虫子交配,当出现两只虫子为同性恋时,便判错。

解题思路:
首先肯定是并查集,将同一类的虫子并到同一个集合。
我刚开始的时候想把所以有关系的虫子并到一个集合,然后通过其到根节点的步数来判断。结果wa了。。
后来学长指点,将虫子分为两个集合,一个为共,一个为母。
如果两字虫子的父节点为同一个,则为同性恋。
如果两只虫子都没有标记过,则将两只虫子分别归为到不同的性别。

代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;int f[2005],sex[2005],r[2005];int find(int x){    if (x!=f[x])        f[x]=find(f[x]);    return f[x];}void uni(int x,int y){    x=find(x);    y=find(y);    if (x==y) return;    else if (r[x]>r[y])        f[y]=x;    else if (r[x]==r[y])    {        r[x]++;        f[y]=x;    }    else        f[x]=y;}int main (){    int t,n,m,i,a,b,p=1;    cin>>t;    while(t--)    {        bool ass=true;        scanf("%d%d",&n,&m);        memset(f,0,sizeof(f));        memset(sex,0,sizeof(sex));        memset(r,0,sizeof(r));        for (i=1; i<=n; i++)            f[i]=i;        for (i=1; i<=m; i++)        {            scanf("%d%d",&a,&b);            if (ass)            {                if (find(a)==find(b))                    ass=false;                else                {                    if (!sex[a])                        sex[a]=b;   //如果a没有被标记过,则使a的异性为b                    else                        uni(sex[a],b);  //否则,将a的父节点和b连接                    if (!sex[b])                        sex[b]=a;                    else                        uni(sex[b],a);                }            }        }        if (!ass)            printf("Scenario #%d:\nSuspicious bugs found!\n",p);        else            printf("Scenario #%d:\nNo suspicious bugs found!\n",p);        p++;        cout<<endl;    }    return 0;}

转载自:http://blog.csdn.net/sio__five/article/details/8813764

原创粉丝点击