hdu 1116 Play on Words(欧拉通路)

题意:给出给出n个单词,要求判断这些单词能否接龙,规则像成语接龙一样,就是当前单词的尾字母为下一个单词的首字母。

思路:看着像是欧拉通路相关的题目,但是重点就在于怎么抽象出来。

刚开始想了半天没想明白,老想着一个单词作为一个顶点去了,就是没转过来。

看了篇解题报告(http://blog.csdn.net/niushuai666/article/details/6917777) 后想过来了,

应该把单词的首尾字母看成顶点,而这个单词相当于连接顶点的有向边。然后这样想的话,这个图最多就有26个顶点(因为只有26个小写字母,题目要求单词为小写字母),接下来就是怎么判断这个途中是否存在欧拉通路了(即判断是否为半欧拉图或欧拉图)。

关于欧拉图的相关知识,详见:

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

#define MAXN 26//最多26个点

int fa[MAXN];
bool exist[MAXN];//标记点是否存在
int in[MAXN],out[MAXN];//入度,出度
int diff[MAXN];//入度不等于出度的点

int set_find(int d){
    if(fa[d]<0)return d;
    return fa[d]=set_find(fa[d]);
}

void set_join(int x,int y){
    x=set_find(x);
    y=set_find(y);
    if(x!=y)fa[x]=y;
}

int main(){
    int t,n,i;
    char word[1024];//单词
    int a,b;//首字母,尾字母
    int root;//根节点数目
    int m;//入度不等于出度的点的个数
    scanf("%d",&t);
    while(t--){
        memset(fa,-1,sizeof(fa));
        memset(exist,0,sizeof(exist));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        root=0;
        m=0;
        scanf("%d",&n);
        while(n--){
            scanf("%s",word);
            a=word[0]-'a';
            b=word[strlen(word)-1]-'a';
            exist[a]=exist[b]=true;
            ++out[a];
            ++in[b];
            set_join(b,a);//b连到a上
        }
        for(i=0;i<MAXN;++i)
            if(exist[i]&&fa[i]<0)++root;
        if(root>1)printf("The door cannot be opened.\n");//图不连通
        else{
            for(i=0;i<MAXN;++i)
                if(in[i]!=out[i])diff[m++]=i;
            if(m==0)printf("Ordering is possible.\n");//所有点入度等于出度,为欧拉图
            else if(m==2&&(
                        (in[diff[0]]-out[diff[0]]==1&&out[diff[1]]-in[diff[1]]==1)||
                        (out[diff[0]]-in[diff[0]]==1&&in[diff[1]]-out[diff[1]]==1) )
                    )printf("Ordering is possible.\n");//满足半欧拉图条件,为半欧拉图
            else printf("The door cannot be opened.\n");//不是欧拉图,也不是半欧拉图
        }
    }
    return 0;
}
View Code

 

posted @ 2015-08-14 20:17  gongpixin  阅读(237)  评论(0编辑  收藏  举报