HDU 1272 并查集

题意:看题,中文题;

思路:坐这题的时候SB了

要同时保证连通性和唯一路径;

先用并查集建图,建图时要注意不能让已经在同一条路里的两个节点,通过另外的路连接起来。

如果结束之后,所有的节点都满足并查集的条件了,再检查一下是不是他们都是连通的,即是否他们都有同一个父结点。

代码很搓,随便看看

AC代码:

#include <stdio.h>
#include <string.h>

int pre[101101],f,s[101101];
int find1(int n)
{
    int t=n;
    while(pre[t]!=t)
    {
        t=pre[t];
    }
    return t;
}

void cnt(int x,int y)//建图
{
    int fx=find1(x);
    int fy=find1(y);
    if(fx!=fy)
    {
        pre[fx]=fy;//如果不在一条路上,连接起来;
    }
    else
    {
        f=1;//如果已经在一条路上了,标记;
    }
    return ;
}

int main()
{
    int n,m,a,b;
    while(~scanf("%d%d",&n,&m))
    {
        f=0;
        if(n==-1&&m==-1)
        {
            break;
        }
        for(int i=1; i<=100000; i++)
        {
            pre[i]=i;
        }
        if(n==0&&m==0)
        {
            printf("Yes
");
        }
        else
        {
            cnt(n,m);
            int a1;
            a1=0;
            s[a1++]=n;
            s[a1++]=m;
            while(1)
            {
                scanf("%d%d",&a,&b);
                s[a1++]=a;
                s[a1++]=b;
                if(a==0&&b==0)
                {
                    break;
                }
                if(a!=b)
                {
                    cnt(a,b);
                }
            }
            if(f==1)
            {
                printf("No
");
            }
            else
            {
                int ans=find1(n);
                int i;
                for(i=1; i<a1-2; i++)//检查连通性,是否有同一个父节点;
                {
                    int l=find1(s[i]);
                    if(l!=ans)
                    {
                        printf("No
");
                        break;
                    }
                }
                if(i==a1-2)
                {
                    printf("Yes
");
                }
            }
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/qioalu/p/4915511.html