uestc 方老师的分身IV

类似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 }

 

你可能感兴趣的:(UE)