hdu1272小希的迷宫

题目大意是给你图的边的数据,问图是否是连通的且无环,满足输出yes,不满足输出no 。
         用并查集就可以了,在联合2个节点的时候,若2个节点的祖先节点是相同的,说明在把这2个节点联合起来之前这2个节点就已经是连通的了,执行了联合这2个节点的操作后,就出现环了.需要注意的是坑点很多


#include<stdio.h>//用并查集判断无向图里是否有回路存在,用拓扑排序判断有向图是否存在回路
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
using namespace std;
#define maxn 100000+5
#define inf 0x3f3f3f3f
int par[maxn],vis[maxn]={0};
int flag=0;
int myfind(int x)
{
    int t=x,tt;
    while(par[t]!=t) t=par[t];
    return t;
}
void unit(int x,int y)
{
    x=myfind(x);
    y=myfind(y);
    if(x==y)
        flag=1;
    else
        par[y]=x;

}
int main()
{
    int u,v;
    int cnt;
    int maxx=0,minn=inf;
    for(int i=1;i<maxn;i++)
        par[i]=i;
    while(scanf("%d%d",&u,&v)!=EOF)
    {
        if(u==-1&&v==-1) return 0;
        if(u==0) {cout<<"Yes"<<endl;continue;}
        for(int i=1;i<maxn;i++)
            par[i]=i;
        memset(vis,0,sizeof(vis));
        flag=0;
        maxx=0;
        minn=inf;
        vis[u]=vis[v]=1;
        maxx=max(max(u,v),maxx);
        minn=min(min(u,v),minn);
        unit(u,v);
        while(scanf("%d%d",&u,&v)!=EOF)
        {
            if(u==0&&v==0)
            {
                if(flag)
                    cout<<"No"<<endl;
                else
                {
                    cnt=0;
                    for(int i=minn;i<=maxx;i++)
                        if(vis[i]&&par[i]==i) cnt++;
                    if(cnt==1)
                        cout<<"Yes"<<endl;
                    else
                        cout<<"No"<<endl;
                }
                break;
            }
            else
            {
                vis[u]=vis[v]=1;
                maxx=max(max(u,v),maxx);
                minn=min(min(u,v),minn);
                if(u==v) flag=1;
                if(!flag)
                    unit(u,v);
            }

        }
    }
}

原文地址:https://www.cnblogs.com/eason9906/p/11755111.html