HDU 1116 Play on Words(欧拉路径(回路))

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

题意:判断n个单词是否可以相连成一条链或一个环,两个单词可以相连的条件是 前一个单词的最后一个字母和后一个单词的第一个字母一样。

分析前提:有(无)向图的欧拉路径判断均是基于连通图
欧拉路径判断:
1、一个无向图存在欧拉路径的充要条件:头节点和尾节点度数为奇数 ;中间节点度数为偶数。
2、一个有向图存在欧拉路径的充要条件:头 入度==出度-1 ;中间 入度==出度 ; 尾 入度==出度+1。
欧拉回路判断:
1、一个无向图存在欧拉回路的充要条件:当且仅当该图所有顶点度数都是偶数。
2、一个有向图存在欧拉回路的充要条件:所有顶点的入度等于出度。
#include<cstdio>
#include<cstring>
int fa[26],in[26],out[26];
int findset(int x)
{
    if(fa[x]==x) return fa[x];
    return fa[x]=findset(fa[x]);
}
bool vis[26];
char s[1010];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        getchar();
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(vis,0,sizeof(vis));
        for(int i=0;i<26;i++) fa[i]=i;
        while(n--){
            gets(s);
            int x=s[0]-'a';
            out[x]++;
            int y=s[strlen(s)-1]-'a';
            in[y]++;
            fa[y]=findset(x);
            vis[x]=vis[y]=1;
        }
        int scc=0;
        for(int i=0;i<26;i++){
            if(vis[i]&&fa[i]==i)
                scc++;
        }
        if(scc>1){//如果不连通 
            printf("The door cannot be opened.
");
            continue;
        }
        bool flag=false;
        int x=0,y=0,z=0;
        for(int i=0;i<26;i++){
            if(vis[i]&&in[i]!=out[i]){
                if(in[i]==out[i]+1)
                    x++;
                else if(in[i]+1==out[i])
                    y++;
                else z++;
            }
        }
        if(z){
            printf("The door cannot be opened.
");
            continue;
        }
        if((x==1&&y==1)||(x==0&&y==0)){
            printf("Ordering is possible.
");
            continue;
        }
        else
            printf("The door cannot be opened.
");
    }
    return 0;
}
 
 
原文地址:https://www.cnblogs.com/freinds/p/6293922.html