题目总体没有难度,做法明确,数据较小。单词做边,首尾字母为点构图。构造output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once 的方法边是每次取边的时候贪心的选择字典序最小的单词。可以用并查集事先判连通和存在性,再求欧拉迹。
顺便练习了一下多重集MultiSets的使用,用平衡树保持边集的字典序以实现lgn时间内插入和删除,由于set不支持键的修改,只能直接在树中删边。
1#include<cstdio>
2#include<cstring>
3#include<set>
4#include<stack>
5#include<string>
6using namespace std;
7struct nod{
8 char str[22];
9 bool operator < (const nod &a)const{
10 return strcmp(a.str,str)>0;
11 }
12}arr[1111];
13multiset<struct nod> _set[26];
14multiset<struct nod>::iterator it;
15stack<string> _sta;
16int degree[26][2];
17int hash[26];
18
19void solve(int s){
20 int k;
21 string str;
22 while(!_set[s].empty()){
23 it=_set[s].begin();
24 k=(*it).str[strlen((*it).str)-1]-'a';
25 str=(*it).str;
26 _set[s].erase(it);
27 solve(k);
28 _sta.push(str);
29 }
30}
31
32int main(){
33 string ss;
34 bool flag;
35 int _case,n,num,i,s,t;
36 int inNum,outNum,inPos,outPos;
37 scanf("%d",&_case);
38 while(_case--){
39 memset(degree,0,sizeof(degree));
40 memset(hash,0,sizeof(hash));
41 while(!_sta.empty()) _sta.pop();
42 for(i=0;i<26;i++) _set[i].clear();
43
44 scanf("%d",&n); getchar();
45 for(i=0;i<n;i++){
46 gets(arr[i].str);
47 s=arr[i].str[0]-'a';
48 t=arr[i].str[strlen(arr[i].str)-1]-'a';
49 _set[s].insert(arr[i]);
50 hash[s]=hash[t]=1;
51 degree[s][0]++; // out
52 degree[t][1]++; // in
53 }
54 for(flag=true,inNum=outNum=i=0;i<26;i++)
55 if(degree[i][0]!=degree[i][1])
56 if(degree[i][0]==degree[i][1]+1){
57 outNum++;
58 outPos=i;
59 }
60 else{
61 if(degree[i][1]==degree[i][0]+1){
62 inNum++;
63 inPos=i;
64 }
65 else{
66 flag=false;
67 break;
68 }
69 }
70 if(!flag){ printf("***\n"); continue; }
71 if(inNum==0&&outNum==0){
72 for(i=0;i<26;i++) if(hash[i]) break;
73 solve(i);
74 }
75 if(inNum==1&&outNum==1) solve(outPos);
76
77 if(_sta.size()==n){ /**//* 基图连通 */
78 ss=_sta.top(); _sta.pop(); printf(ss.c_str());
79 while(!_sta.empty()){
80 ss=_sta.top(); _sta.pop();
81 printf("."); printf(ss.c_str());
82 }printf("\n");
83 }
84 else printf("***\n");
85 }
86 return 0;
87}