单词拼接
时间限制:3000 ms | 内存限制:65535 KB
难度:5
描述
给你一些单词,请你判断能否把它们首尾串起来串成一串。前一个单词的结尾应该与下一个单词的道字母相同。如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
输入
第一行是一个整数N(0<N<20),表示测试数据的组数
每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
输出
如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm
样例输出
aloha.arachnid.dog.gopher.rat.tiger
***
来源
Waterloo local 2003.01.25 /POJ
上传者
张云聪
解题:判欧拉路径+连通
有向图存在欧拉路径的条件是所有点的入度等于出度,或者一个点的入度比出度大一,为终点,一点的出度比入度大一,为始点,其余的点入度等于出度。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #include <cstdlib> 10 #include <string> 11 #include <set> 12 #include <stack> 13 #define LL long long 14 #define pii pair<int,int> 15 #define INF 0x3f3f3f3f 16 using namespace std; 17 const int maxn = 1010; 18 struct arc { 19 int to,next; 20 char str[30]; 21 }; 22 arc e[maxn]; 23 int head[maxn],uf[maxn],d[maxn],tot,n,m,cnt; 24 string str[maxn]; 25 bool vis[maxn]; 26 char ans[maxn][30]; 27 bool cmp(const string &a,const string &b) { 28 return a > b; 29 } 30 void add(int u,int v,string &s) { 31 e[tot].to = v; 32 e[tot].next = head[u]; 33 strcpy(e[tot].str,s.c_str()); 34 head[u] = tot++; 35 } 36 int Find(int x) { 37 if(x != uf[x]) uf[x] = Find(uf[x]); 38 return uf[x]; 39 } 40 void dfs(int u,int id){ 41 for(int i = head[u]; ~i; i = e[i].next){ 42 if(!vis[i]){ 43 vis[i] = true; 44 dfs(e[i].to,i); 45 } 46 } 47 if(id > -1) strcpy(ans[cnt++],e[id].str); 48 } 49 int main() { 50 scanf("%d",&n); 51 while(n--) { 52 scanf("%d",&m); 53 for(int i = tot = 0; i < m; ++i) 54 cin>>str[i]; 55 sort(str,str+m,cmp); 56 memset(vis,false,sizeof(vis)); 57 memset(head,-1,sizeof(head)); 58 for(int i = 0; i < 26; ++i) { 59 d[i] = 0; 60 uf[i] = i; 61 } 62 for(int i = 0; i < m; ++i) { 63 int u = str[i][0] - 'a'; 64 int v = str[i][str[i].length() - 1] - 'a'; 65 d[v]--; 66 d[u]++; 67 add(u,v,str[i]); 68 int tx = Find(u); 69 int ty = Find(v); 70 if(tx != ty) uf[tx] = ty; 71 vis[u] = vis[v] = true; 72 } 73 int root = 0,st = -1,a = 0,b = 0; 74 bool flag = true; 75 for(int i = 0; i < 26; ++i){ 76 if(vis[i]){ 77 if(i == uf[i]) root++; 78 if(root > 1){ 79 flag = false; 80 break; 81 } 82 if(st == -1) st = i; 83 if(abs(d[i]) > 1) { 84 flag = false; 85 break; 86 } 87 if(d[i] == 1){ 88 st = i; 89 a++; 90 } 91 if(d[i] == -1) b++; 92 } 93 } 94 if(flag &&(a == b && b == 1 || a == b && b == 0)){ 95 memset(vis,false,sizeof(vis)); 96 cnt = 0; 97 dfs(st,-1); 98 for(int i = cnt-1; i >= 0; i--) 99 printf("%s%c",ans[i],i?'.':'\n'); 100 }else puts("***"); 101 } 102 return 0; 103 }