太无语了。
这道题做了一整天。
主要还是我太弱了。
以后这个就当输出欧拉路径的模版吧。
题目中的输出字典序最小我有点搞不清楚,看了别人是这么写的。但是我发现我过不了后面DISCUSS里面的数据。
题意理解问题还是题目问题?
这道题大致以下分几步吧。
判断图是否连通,用并查集判断即可。
判断图是否有欧拉回路或者通路,判断出度和入度即可,若是欧拉通路,找出起点。
DFS找出欧拉路径输出。
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cmath> #include <cstring> #include <queue> #include <set> #include <vector> #include <stack> #include <map> #include <iomanip> #define PI acos(-1.0) #define Max 2505 #define inf 1<<28 #define LL(x) ( x << 1 ) #define RR(x) ( x << 1 | 1 ) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) #define mp(a,b) make_pair(a,b) #define PII pair<int,int> #define N 10005 using namespace std; inline void RD(int &ret) { char c; do { c = getchar(); } while(c < '0' || c > '9') ; ret = c - '0'; while((c=getchar()) >= '0' && c <= '9') ret = ret * 10 + ( c - '0' ); } inline void OT(int a) { if(a >= 10)OT(a / 10) ; putchar(a % 10 + '0') ; } char a[N] ; vector<string>g[300] ; int in[N] ,out[N] ; int vis[N] ; int f[N] ; int n ; int first ; int find(int x) { return f[x] == x ? x : f[x] = find(f[x]) ; } void Union(int a ,int b) { a = find(a) ; b = find(b) ; if(a == b)return ; if(a > b)f[a] = b ; else f[b] = a ; } void init() { mem(in , 0) ; mem(out ,0) ; for (int i = 0 ; i < 260 ; i ++ )f[i] = i ; for (int i = 0 ; i < 260 ; i ++ )g[i].clear() ; first = 0 ; mem(vis, 0) ; } stack<string>ans ; void dfs(int now ){ int sz = g[now].size() ; while(g[now].size() > 0){ string nn = g[now][0] ; int tt = g[now][0][g[now][0].size() - 1] - 'a' ; g[now].erase(g[now].begin()) ; dfs(tt) ; ans.push(nn) ; } } int main() { int T ; #ifndef ONLINE_JUDGE freopen("D:\acm.txt","r",stdin) ; #endif cin >> T ; while(T -- ) { cin >> n ; init() ; for (int i = 1 ; i <= n ; i ++ ) { scanf("%s",a) ; int s = a[0] - 'a' ; int e = a[strlen(a) - 1] - 'a' ; out[s] ++ ; in[e] ++ ; g[s].push_back(a) ; Union(s , e) ; vis[s] = vis[e] = 1 ; } int fnum = 0 ; int dnum = 0 ; bool flag = 0 ; int st = -1 ; for (int i = 0 ; i < 26 ; i ++ ) { if(!vis[i])continue ; if(i == find(i))fnum ++ ; if(in[i] - out[i] == 1){ dnum ++ ; } if(out[i] - in[i] == 1){ dnum ++ ; st = i ; } if(abs(out[i] - in[i]) >= 2){ flag = 1 ; } } if((dnum == 1 || dnum > 2) ||(flag) || (fnum != 1)) { puts("***") ; continue ; } else{ for (int i = 0 ;i < 26; i ++ ){ if(st == -1 && vis[i])st = i ;//如果是欧拉回路,则找到字典序最小的起点。 sort(g[i].begin() , g[i].end()) ; } while(!ans.empty())ans.pop() ; dfs(st) ; printf("%s",ans.top().c_str()) ; ans.pop() ; while(!ans.empty()){ printf(".%s",ans.top().c_str()) ; ans.pop() ; } puts("") ; } } return 0 ; }