poj 2337 Catenyms (边最小字典序欧拉路径 Fleury)

来源:互联网 发布:数据流程图例题购票 编辑:程序博客网 时间:2024/05/14 12:27

题目链接:   poj 2337

题目大意:   给出N个单词,单词A的开头与另外单词B结尾相同

                  则单词A和单词B可以连起来,问是否可以把所有单词都串成一条线

                  输出最小字典序的(按单词的字典序串)

解题思路:   对于每个单词,把单词的起点和终点字母当作顶点

                  这个单词即是起点到终点的一条单向边

                  根据有向图的欧拉图判断,若顶点的出度-入度为0,或者一个为1一个为-1则是欧拉通路

                  根据题意还可能是不连通的图,所以最后在判断一下是否是联通图

                  PS:欧拉路径的问题要记得判断图是否联通

代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAX 2010#define INF 0x3f3f3fusing namespace std;int k,Index,visit[MAX],pre[50],In[50],To[50],ans[MAX];struct snode{int len;char ch[25];}num[MAX];struct node{int to,next,w;}edge[MAX<<3];void Add_edge(int a,int b,int w){edge[Index].to=b;edge[Index].w=w;edge[Index].next=pre[a];pre[a]=Index++;}bool cmp(struct snode a,struct snode b){    if(strcmp(a.ch,b.ch)>=0)        return false;    return true;}void Fleury(int start){int i,v;for(i=pre[start];i!=-1;i=edge[i].next){v=edge[i].to;if(!visit[edge[i].w]){visit[edge[i].w]=1;Fleury(v);ans[++k]=edge[i].w; //记录边的访问顺序}}}int main(){char ch1[25];int t,i,j,n,m,a,b,pd,pd1,pd2,start;scanf("%d",&t);while(t--){Index=pd1=pd2=k=0;memset(visit,0,sizeof(visit));memset(pre,-1,sizeof(pre));memset(num,0,sizeof(num));memset(In,0,sizeof(In));memset(To,0,sizeof(To));scanf("%d",&n);for(i=1;i<=n;i++){scanf("%s",num[i].ch);num[i].len=strlen(num[i].ch);}sort(num+1,num+1+n,cmp);start=INF;for(i=n;i>=1;i--){a=num[i].ch[0]-'a'+1;b=num[i].ch[num[i].len-1]-'a'+1;Add_edge(a,b,i);To[a]++,In[b]++;if(start>a)start=a;if(start>b)start=b;}m=-1;for(i=1;i<=26;i++){if(To[i]-In[i]==1){if(m==-1)m=i;pd1++;}else if(To[i]-In[i]==-1)                pd2++;            else if(To[i]!=In[i])            {                pd1=3;                break;            }}if(pd1==1&&pd2==1)    //若出度-入度之差为1和-1的点各有一个,起点是值1的    start=m;else if(pd1==0&&pd2==0)  //不存在则选序号最小的顶点start=start;else        {            printf("***\n");continue;        }Fleury(start);if(k!=n)       //判断图是否联通{printf("***\n");continue;}for(i=k;i>=1;i--){printf("%s%c",num[ans[i]].ch,".\n"[i==1]);}}return 0;}


1 0