HDU 1116

http://acm.hdu.edu.cn/showproblem.php?pid=1116

判断有向图欧拉回路和欧拉通路

有向图:

欧拉回路:图联通,所有顶点出度等于入度(通过图中每条边且只通过一次,并且经过每一顶点的回路。)

欧拉通路:图联通,除起点终点所有顶点出度等于入度,起点的出度-入度=1,终点的入度-出度=1(通过图中每条边且只通过一次,并且经过每一顶点的通路。)

图联通均用并查集判断

#include <iostream>

#include <cstdio>

#include <cstring>



using namespace std ;

int idx[100005] ;

int find(int x)

{

    return idx[x]==x?x:idx[x]=find(idx[x]) ;

}



int IN[100005],OUT[100005] ;

char s[100005] ;

int main()

{

    int t ;

    scanf("%d",&t) ;

    while(t--)

    {

        int n ;

        scanf("%d",&n) ;

        memset(IN,0,sizeof(IN)) ;

        memset(OUT,0,sizeof(OUT)) ;

        for(int i=0 ;i<26 ;i++)

            idx[i]=i ;

        int flag[30] ;

        memset(flag,0,sizeof(flag)) ;

        for(int i=0 ;i<n ;i++)

        {

            scanf("%s",s) ;

            int x=s[0]-'a' ;

            int y=s[strlen(s)-1]-'a' ;

            int p=find(x) ;

            int q=find(y) ;

            if(p!=q)

            {

                idx[p]=q ;

            }

            flag[x]=flag[y]=1 ;

            IN[x]++ ;

            OUT[y]++ ;

        }

        int cnt=0 ;

        for(int i=0 ;i<26 ;i++)

        {

            if(flag[i] && find(i)==i)cnt++ ;

        }

        if(cnt!=1)puts("The door cannot be opened.") ;

        else

        {

            cnt=0 ;

            int ans[30] ;

            for(int i=0 ;i<26 ;i++)

            {

                if(flag[i] && IN[i]!=OUT[i])

                {

                    ans[cnt++]=i ;

                }

            }

            if(!cnt)

            {

                puts("Ordering is possible.") ;

                continue ;

            }

            if(cnt==2 && ((OUT[ans[0]]-IN[ans[0]]==1 && IN[ans[1]]-OUT[ans[1]]==1) || (OUT[ans[1]]-IN[ans[1]]==1 && IN[ans[0]]-OUT[ans[0]]==1)))

                puts("Ordering is possible.") ;

            else

                puts("The door cannot be opened.") ;

        }

    }

    return 0 ;

}
View Code

 

你可能感兴趣的:(HDU)