标签:
类似POJ1386,参考的大神的博客
首先明确思路:
是否为连通图(并查集解决) -> 是否存在欧拉路径 -> 是否存在欧拉回路 (是,则选取字典序最小的输出,否则直接输出可行解)
注意区分有向图和无线图存在欧拉路径或者欧拉回路的条件:
无向图: G为连通图,并且G仅有两个奇度节点或者无奇度节点
推论:1.当G是仅有两个奇度节点的连通图时,G的欧拉通路必以此两个结点为端点
2.当G时无奇度结点的连通图时,G必有欧拉回路
3.G为欧拉图(存在欧拉回路)的充分必要条件是G为无奇度节点的连通图
有向图:D为有向图,D的基图连通,并且所有顶点的出度与入度相等;或者除两个定点外,其余顶点的出度和入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为1
推论:1.当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度都相等时,D的有向欧拉通路必以出入度之差为1的顶点作为始点,以出入度之差为-1的顶点作为终点
2.当D的所有顶点的出入度都相等时,D中存在有向欧拉回路
3.有向图D为有向欧拉回路的充分必要条件是D的基图为连通图,并且所有顶点的出入度都相等
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<climits> 11 #include<string.h> 12 #include<cmath> 13 #include<stdlib.h> 14 #include<vector> 15 #include<stack> 16 #define INF 1000000007 17 #define MAXN 40010 18 #define Mod 1000007 19 #define N 2010 20 #define NN 30 21 #define sigma_size 3 22 const int maxn = 6e5 + 10; 23 using namespace std; 24 typedef long long LL; 25 26 struct node{ 27 int u, v, next; 28 string w; 29 }G[N]; 30 31 int head[NN], fa[NN], ind[NN], outd[NN], vis[NN]; 32 int t, cnt, start, k; 33 int evis[N]; 34 string ss[N]; 35 string ans[N]; 36 int T, n; 37 38 bool cmp(string a, string b) 39 { 40 return a > b; 41 } 42 43 int findset(int x) 44 { 45 if (fa[x] == x) return x; 46 return fa[x] = findset(fa[x]); 47 } 48 49 void merg(int a, int b) 50 { 51 int x = findset(a); 52 int y = findset(b); 53 if (y != x) { 54 fa[x] = y; 55 } 56 } 57 58 void addedge(int u, int v, string w) 59 { 60 G[t].u = u; 61 G[t].v = v; 62 G[t].w = w; 63 G[t].next = head[u]; 64 head[u] = t++; 65 outd[u]++; 66 ind[v]++; 67 vis[u] = vis[v] = 1; 68 merg(u, v); 69 } 70 71 void read() 72 { 73 cin >> n; 74 for (int i = 1; i <= n; ++i) 75 cin >> ss[i]; 76 sort(ss + 1, ss + n + 1, cmp); 77 for (int i = 1; i <= n; ++i) { 78 int u = ss[i][0] - ‘a‘; 79 int v = ss[i][ss[i].length() - 1] - ‘a‘; 80 addedge(u, v, ss[i]); 81 } 82 } 83 84 void init() 85 { 86 t = 1; 87 for (int i = 0; i < 30; ++i) 88 fa[i] = i; 89 memset(ind, 0, sizeof(ind)); 90 memset(outd, 0, sizeof(outd)); 91 for (int i = 0; i <= 2000; i++) 92 { 93 G[i].u = G[i].v = G[i].next = 0; 94 G[i].w = ""; 95 } 96 memset(head, -1, sizeof(head)); 97 memset(evis, 0, sizeof(evis)); 98 memset(vis, 0, sizeof(vis)); 99 for (int i = 0; i < 2010; ++i) 100 ans[i] = ""; 101 } 102 103 bool Euler_Path() 104 { 105 int one = 0; 106 int none = 0; 107 int tot = 0; 108 start = -1; 109 for (int i = 0; i < 26; ++i) { 110 if (vis[i] == 0) continue; 111 //int tmp = findset(i); 112 if (findset(i) == i) tot++; 113 //cout << tot << endl; 114 if (ind[i] == outd[i] + 1) none++; 115 else if (ind[i] + 1 == outd[i]) { 116 one++; 117 start = i; 118 } 119 else if (ind[i] != outd[i]) 120 return false; 121 } 122 if (tot != 1) return false; 123 if ((one == none && one == 1) || (one == none && one == 0)) { 124 if (start == -1) { 125 for (int i = 0; i < 26; ++i) { 126 if (vis[i] && outd[i] > 0) { 127 start = i; 128 return true; 129 } 130 } 131 } 132 if (one == none && one == 1) return true; 133 return false; 134 } 135 return false; 136 } 137 138 139 void dfs(int v, int flag) 140 { 141 for (int i = head[v]; i != -1; i = G[i].next) { 142 if (!evis[i]){ 143 evis[i] = 1; 144 dfs(G[i].v, i); 145 } 146 } 147 if (flag != -1) 148 ans[cnt++] = G[flag].w; 149 } 150 void process() 151 { 152 init(); 153 read(); 154 if (Euler_Path()) { 155 cnt = 0; 156 dfs(start, -1); 157 for (int i = cnt - 1; i >= 0; --i) { 158 cout << ans[i]; 159 if (i != 0) cout << "."; 160 else cout << endl; 161 } 162 } 163 else puts("***"); 164 } 165 166 int main() 167 { 168 cin >> T; 169 while (T--) { 170 process(); 171 } 172 //system("pause"); 173 return 0; 174 }
标签:
原文地址:http://www.cnblogs.com/usedrosee/p/4300314.html