给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
aloha.arachnid.dog.gopher.rat.tiger ***
欧拉图或半欧拉图都是能成功拼接的。
1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数);
2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点;
3.有向连通图D是欧拉图,当且仅当该图为连通图且D中每个结点的入度=出度
4.有向连通图D含有欧拉通路,当且仅当该图为连通图且D中除两个结点外,其余每个结点的入度=出度,且此两点满足deg-(u)-deg+(v)=±1。(起始点s的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度)
5.一个非平凡连通图是欧拉图当且仅当它的每条边属于奇数个环。
6.如果图G是欧拉图且 H = G - uv,则H有奇数个u,v-迹仅在最后访问v;同时,在这一序列的u,v-迹中,不是路径的迹的条数是偶数。
#include <string.h> #include <stdio.h> #include <stdlib.h> #define Maxsize 1010 struct Node{ int to; }e[30][100]; int indegree[30]; int outdegree[30]; int next[Maxsize]; char str[Maxsize][35]; int que[Maxsize]; bool vis[Maxsize]; int top; int m; int count; int cmp(const void *a,const void *b) { return strcmp((char *)a,(char *)b); } void init() { for(int i=0;i<30;i++) {e[i][0].to=0;} memset(indegree,0,sizeof(indegree)); memset(outdegree,0,sizeof(outdegree)); memset(vis,0,sizeof(vis)); count=m;top=0; } bool dfs(int u,int c) { if(c==count) return true; for(int i=1;i<=e[u][0].to;i++) { Node &E=e[u][i]; if(!vis[E.to]) { vis[E.to]=1; que[top++]=E.to; if(dfs(next[E.to],c+1)) return true; top--; vis[E.to]=0; } } return false; } int main() { int n; int i; scanf("%d",&n); while(n--) { scanf("%d",&m); int l,r; init(); for(i=0;i<m;i++) { scanf("%s",str[i]); } qsort(str,m,sizeof(str[0]),cmp); for(i=0;i<m;i++) { // printf("%s\n",str[i]); l=str[i][0]-'a'; int t=++e[l][0].to;e[l][t].to=i; r=strlen(str[i])-1; next[i]=str[i][r]-'a'; outdegree[l]++;indegree[next[i]]++; } int flag=0; for(i=0;i<26;i++) if(indegree[i]!=outdegree[i]) flag++; // printf("%d\n",flag); if(flag!=2&&flag!=0) { printf("***\n"); continue; } if(flag==2) { for(i=0;i<26;i++) if(outdegree[i]-1==indegree[i]) { dfs(i,0); break; } } else dfs(0,0); if(top!=m) { printf("***\n"); continue; } for(i=0;i<top-1;i++) printf("%s.",str[que[i]]); printf("%s\n",str[que[top-1]]); } return 0; }