【并查集】小希的迷宫--判断成环

//并查集判断是否成环
//记录有几个老大(几个集合),不成环是1


#include<stdio.h>
#include<iostream>
#include<string.h>
#define maxn 100005
using namespace std;

int ac[maxn];
int vis[maxn];//出现的点做标记
int k;
int find(int u){
    if(u!=ac[u]){
        ac[u]=find(ac[u]);
    }
    return ac[u];
}
void  join(int x,int y){
    int fx=find(x);
    int fy=find(y);
/*两个点find(x)==find(y),说明他们是一个集合的(k=1),
如果再连接a,b两个点,就会构成回路,输出no.    */
    if(fx!=fy){
        ac[fy]=fx;
    }
    else{
        k=0;
    }

}
int main(){
    int x,y;
        while (scanf("%d%d",&x,&y),x!=-1||y!=-1){
            if (x==0&&y==0)
            {
                printf("Yes\n"); continue;
            }
        
    //初始化
    for(int i=0;i<maxn;i++){
        ac[i]=i;    
        vis[i]=0;
    }
    if(x==-1 && y==-1)
        break;
        join(x,y);
        k=1;
        vis[x]=1;
        vis[y]=1;
    while(scanf("%d%d",&x,&y) && x && y)
        {
           join(x,y);
            vis[x]=1;
            vis[y]=1;
        }
        if(k==0)
        {
            printf("No\n");
             continue;
        }        
        else
        {
            /*1到100000这些个点都进行判断,如果标记过
            (表示这个点出现过)并且f[i]==i(自己就是老大),表示有一个集合了,有几个老大有几个集合
            这里如果集合大于1,输出NO*/
            int sum=0;
            for(int i=0;i<=maxn;i++)
            {
                if(vis[i]&&ac[i]==i)
                sum++;
            }
            if(sum!=1)
            {
              printf("No\n");
            }
            else
            {
                printf("Yes\n");
            }

        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39905871/article/details/81184274