Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9454 | Accepted: 2486 |
Description
dog.gopher gopher.rat rat.tiger aloha.aloha arachnid.dog
Input
Output
Sample Input
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger ***分析:
题目的意思是给出来n个单词,看看是否能连成一条单词串,要把每个单词都搜索一遍很容易想到是欧拉通路,以每个单词的首字母和末字母为定点建边,权值状态为该单词,编号a,b,c……为1,2,3,……
首先用并查集判断改图是否是连通图不是的话输出***
然后判断该图是欧拉通路还是欧拉回路,若是欧拉回路的话从最小的点开始深搜,若是欧拉通路的话从出度比入度大一的点开始深搜,否则输出***
此题还让输出结果保证字典序最小,让单词按照逆序快排即可
定义:
1.无向图存在欧拉回路的充要条件:
连通且没有奇度顶点。
2.无向图存在欧拉路径的充要条件:
连通且奇度顶点个数为2。
3.有向图存在欧拉路径的充要条件:
基图连通且存在某顶点入度比出度大1,另一顶点出度比入度大1,其余顶点入度等于出
4.有向图存在欧拉回路的充要条件:
基图连通且所有顶点入度等于出度。
程序:
#include"stdio.h" #include"string.h" #include"queue" #include"stack" #include"iostream" #include"string" #include"map" #include"stdlib.h" #define inf 99999999 #define M 10009 using namespace std; struct st { int u,v,w,next,vis; }edge[M]; int head[M],use[M],s[M],out[M],in[M]; int t,num; int f[M]; int finde(int x) { if(x!=f[x]) f[x]=finde(f[x]); return f[x]; } void make(int a,int b) { f[finde(a)]=finde(b); } int cmp(const void *a,const void *b) { return strcmp((char *)b,(char *)a); } void init() { t=0; memset(head,-1,sizeof(head)); memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); memset(use,0,sizeof(use)); memset(edge,0,sizeof(edge)); for(int i=0;i<=100;i++) f[i]=i; } void add(int u,int v,int w) { edge[t].u=u; edge[t].v=v; edge[t].w=w; edge[t].next=head[u]; head[u]=t++; } void DFS(int u) { for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!edge[i].vis) { edge[i].vis=1; DFS(v); s[num++]=edge[i].w; } } } char ch[M][111]; int main() { int T,i,a,b,n,m; scanf("%d",&T); while(T--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%s",ch[i]); qsort(ch,n,sizeof(ch[0]),cmp); init(); for(i=0;i<n;i++) { m=strlen(ch[i]); a=ch[i][0]-'a'+1; b=ch[i][m-1]-'a'+1; use[a]=1; use[b]=1; make(a,b); add(a,b,i); out[a]++; in[b]++; } int tmp=finde(a); int flag=0; for(i=1;i<=26;i++) { if(use[i]&&finde(i)!=tmp) flag++; } if(flag) { printf("***\n");continue; } int f1=0,f2=0,ff=0; for(i=1;i<=26;i++) { if(!use[i]) continue; if(out[i]-in[i]>1||in[i]-out[i]>1) ff++; if(out[i]==in[i]+1) f1++; if(out[i]+1==in[i]) f2++; } if(f1==0&&f2==0&&ff==0) { num=0; for(i=1;i<=26;i++) { if(use[i]) { DFS(i); break; } } for(i=num-1;i>=0;i--) { if(i==num-1) printf("%s",ch[s[i]]); else printf(".%s",ch[s[i]]); } printf("\n"); } else if(f1==1&&f2==1&&ff==0) { num=0; for(i=1;i<=26;i++) { if(use[i]&&in[i]+1==out[i]) { DFS(i); break; } } for(i=num-1;i>=0;i--) { if(i==num-1) printf("%s",ch[s[i]]); else printf(".%s",ch[s[i]]); } printf("\n"); } else printf("***\n"); } }