hdu1272&&1325--並查集判環及森林問題

題意:給一個圖,如果圖裏有環或者是森林就輸出"No"

注意空圖算"Yes"

並查集判環:合併集合時,如果出現自己並自己的情況,就說明出現了環

1272:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int parent[maxn],ranc[maxn];
int serc(int pos)
{
    while(parent[pos]!=pos)
    {
        pos=parent[pos];
    }
    return pos;
}
void init()
{
    for(int i=0;i<=maxn;i++)
    {
        parent[i]=i;
        ranc[i]=1;
    }

}
void merg(int x,int y)
{
    x=serc(x);
    y=serc(y);
    if(ranc[x]<ranc[y])
    parent[x]=parent[y];
    else
    {
        if(ranc[x]==ranc[y])ranc[x]++;
        parent[y]=parent[x];
    }
}
void compress(int pos)
{
    int tpos=serc(pos);
    int cur;
    while(parent[pos]!=pos)
    {
        cur=parent[pos];
        parent[pos]=tpos;
        pos=cur;
    }
}

bool s[maxn];
int main()
{
    int t,m,n,cur1,cur2;
    bool flag;

    while(cin>>cur1>>cur2,cur1!=-1)
    {
        if(cur1==0&&cur2==0)
        {
            cout<<"Yes"<<endl;
        }
        else
        {
          memset(s,false,sizeof(s));
        flag=false;
        init();
        int maxn=0;
        if(cur1>maxn)maxn=cur1;
        if(cur2>maxn)maxn=cur2;
        s[cur1]=true;
        s[cur2]=true;
        if(serc(cur1)==serc(cur2))
            flag=true;
            merg(cur1,cur2);
        while(cin>>cur1>>cur2,cur1!=0)
        {
             s[cur1]=true;
        s[cur2]=true;
           if(serc(cur1)==serc(cur2))flag=true;
            merg(cur1,cur2);
            if(cur1>maxn)maxn=cur1;
        if(cur2>maxn)maxn=cur2;
        }


        int sum=0;
        if(!flag)
        for(int i=1;i<=maxn;i++)
        {
            if(parent[i]==i&&s[i]){if(sum==0)sum++;else{flag=true;break;}}
        }
        if(flag)cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
        }

    }
    return 0;
}

1325把樹搞成了有向邊

只需要在上面那題代碼裏面加一個記錄每個點有沒有過雙親節點

//還有一點,輸入結束標誌是負數而不是-1 -1

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+10;
    int parent[maxn],ranc[maxn];
    bool hasparent[maxn];
    int serc(int pos)
    {
        while(parent[pos]!=pos)
        {
            pos=parent[pos];
        }
        return pos;
    }
    void init()
    {
        for(int i=0;i<=maxn;i++)
        {
            parent[i]=i;
            ranc[i]=1;
        }

    }
    void merg(int x,int y)
    {
        x=serc(x);
        y=serc(y);
        if(ranc[x]<ranc[y])
        parent[x]=parent[y];
        else
        {
            if(ranc[x]==ranc[y])ranc[x]++;
            parent[y]=parent[x];
        }
    }
    void compress(int pos)
    {
        int tpos=serc(pos);
        int cur;
        while(parent[pos]!=pos)
        {
            cur=parent[pos];
            parent[pos]=tpos;
            pos=cur;
        }
    }

    bool s[maxn];
    int main()
    {
        int t,m,n,cur1,cur2,ppp=0;
        bool flag;


        while(cin>>cur1>>cur2,cur1>=0)
        {
            if(cur1==0&&cur2==0)
            {
                cout<<"Case "<<++ppp<<" is a tree."<<endl;
            }
            else
            {
              memset(s,false,sizeof(s));
              memset(hasparent,false,sizeof(hasparent));
              hasparent[cur2]=true;
            flag=false;
            init();
            int maxn=0;
            if(cur1>maxn)maxn=cur1;
            if(cur2>maxn)maxn=cur2;
            s[cur1]=true;
            s[cur2]=true;
            if(serc(cur1)==serc(cur2))
                flag=true;
                merg(cur1,cur2);
            while(cin>>cur1>>cur2,cur1!=0)
            {
                if(!flag)
                {
                   if(hasparent[cur2]){flag=true;}
                hasparent[cur2]=true;
                 s[cur1]=true;
            s[cur2]=true;
               if(serc(cur1)==serc(cur2))flag=true;
                merg(cur1,cur2);
                if(cur1>maxn)maxn=cur1;
            if(cur2>maxn)maxn=cur2;
                }

            }


            int sum=0;
            if(!flag)
            for(int i=1;i<=maxn;i++)
            {
                if(parent[i]==i&&s[i]){if(sum==0)sum++;else{flag=true;break;}}
            }
            if(flag)cout<<"Case "<<++ppp<<" is not a tree."<<endl;
            else cout<<"Case "<<++ppp<<" is a tree."<<endl;
            }

        }
        return 0;
    }



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章