UVA 10735 混合图的欧拉回路判断以及输出路径
题意和POJ1635一样,只是多了一项输出路径。
1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <string>
5 #include <cstring>
6 #include <cmath>
7 #include <vector>
8 #include <queue>
9 #include <algorithm>
10 #include <map>
11 using namespace std;
12 const int maxn = 220;
13 const int maxm = maxn*maxn;
14 const int INF = 0x3f3f3f3f;
15 struct Edge
16 {
17 int from, to, cap, flow;
18 Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}
19 };
20 struct Dinic
21 {
22 int n, m, s, t;
23 vector<Edge> edges;
24 vector<int> G[maxn];
25 bool vis[maxn];
26 int d[maxn];
27 int cur[maxn];
28 void init(int n)
29 {
30 this->n = n;
31 for(int i = 0; i <= n; i++) G[i].clear();
32 edges.clear();
33 }
34 void ClearFlow ()
35 {
36 for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;
37 }
38 void AddEdge(int from, int to, int cap)
39 {
40 edges.push_back(Edge (from, to, cap, 0));
41 edges.push_back(Edge (to, from, 0, 0));
42 m = edges.size();
43 G[from].push_back(m-2);
44 G[to].push_back(m-1);
45 }
46 bool BFS()
47 {
48 memset(vis, 0, sizeof(vis));
49 queue<int> Q;
50 Q.push(s);
51 d[s] = 0;
52 vis[s] = 1;
53 while(!Q.empty())
54 {
55 int x = Q.front();
56 Q.pop();
57 for(int i = 0; i < G[x].size(); i++)
58 {
59 Edge& e = edges[G[x][i]];
60 if(!vis[e.to] && e.cap > e.flow)
61 {
62 vis[e.to] = 1;
63 d[e.to] = d[x]+1;
64 Q.push(e.to);
65 }
66 }
67 }
68 return vis[t];
69 }
70 int DFS(int x, int a)
71 {
72 if(x == t || a == 0) return a;
73 int flow = 0, f;
74 for(int &i = cur[x]; i < G[x].size(); i++)
75 {
76 Edge& e = edges[G[x][i]];
77 if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0)
78 {
79 e.flow += f;
80 edges[G[x][i]^1].flow -= f;
81 flow += f;
82 a -= f;
83 if(a == 0) break;
84 }
85 }
86 return flow;
87 }
88 int Maxflow(int s, int t)
89 {
90 this->s = s;
91 this->t = t;
92 int flow = 0;
93 while(BFS())
94 {
95 memset(cur, 0, sizeof(cur));
96 flow += DFS(s, INF);
97 }
98 return flow;
99 }
100 };
101 int fa[maxn];
102 int find(int x)
103 {
104 return x == fa[x]? x : fa[x] = find(fa[x]);
105 }
106 void Union(int x, int y)
107 {
108 x = find(x), y = find(y);
109 if(x != y) fa[x] = y;
110 }
111 Dinic dinic;
112 int n, m, s, t;
113 int ind[maxn], outd[maxn];
114 bool vis[maxn];
115 struct Edge2
116 {
117 int v;
118 bool vis;
119 int next;
120 } edge[maxm];
121 int cnt;
122 int first[maxn];
123 void addedge(int u, int v)
124 {
125 edge[cnt].v = v, edge[cnt].vis = 0;
126 edge[cnt].next = first[u], first[u] = cnt++;
127 }
128 void init()
129 {
130 cnt = 0;
131 memset(first, -1, sizeof(first));
132 memset(ind, 0, sizeof(ind));
133 memset(outd, 0, sizeof(outd));
134 memset(vis, 0, sizeof(vis));
135 for(int i = 0; i <= n+2; i++) fa[i] = i;
136 }
137 void read_case()
138 {
139 scanf("%d%d",&n,&m);
140 init();
141 dinic.init(n+5);
142 while(m--)
143 {
144 int x, y;
145 char c;
146 scanf("%d %d %c", &x, &y, &c);
147 if(c == 'D')
148 addedge(x, y);
149 else if(c == 'U')
150 dinic.AddEdge(x, y, 1);
151 vis[x] = vis[y] = 1;
152 outd[x]++, ind[y]++;
153 Union(x, y);
154 }
155 }
156 int totflow;
157 int build()
158 {
159 s = 0, t = n+1;
160 totflow = 0;
161 for(int i = 1; i <= n; i++)
162 if(vis[i])
163 {
164 if((outd[i]+ind[i]) & 1)
165 return 0;
166 else if(outd[i] > ind[i])
167 {
168 int d = outd[i]-ind[i];
169 dinic.AddEdge(s, i, d/2);
170 totflow += d/2;
171 }
172 else if(ind[i] > outd[i])
173 {
174 int d = ind[i]-outd[i];
175 dinic.AddEdge(i, t, d/2);
176 }
177 }
178 return 1;
179 }
180 int check()
181 {
182 int count = 0;
183 for(int i = 1; i <= n; i++) if(vis[i] && fa[i] == i) count++;
184 if(count > 1) return 0;
185
186 int ans = dinic.Maxflow(s, t);
187 if(ans >= totflow) return 1;
188 return 0;
189 }
190 void rebuild()
191 {
192 for(int i = 0; i < dinic.edges.size(); i++)
193 {
194 Edge &e = dinic.edges[i];
195 if(e.cap > 0 && e.from >= 1 && e.from <= n)
196 {
197 if(e.flow == 0) addedge(e.from, e.to);
198 else addedge(e.to, e.from);
199 }
200 }
201 }
202 vector<int> ans;
203 int Euler(int u) //套圈算法
204 {
205 for(int e = first[u]; e != -1; e = edge[e].next)
206 {
207 if(edge[e].vis) continue;
208 edge[e].vis = 1;
209 Euler(edge[e].v);
210 ans.push_back(edge[e].v);
211 }
212 }
213 void output()
214 {
215 ans.clear();
216 Euler(1);
217 printf("1");
218 for(int i = ans.size()-1; i >= 0; i--)
219 printf(" %d", ans[i]);
220 printf("\n");
221 }
222 void solve()
223 {
224 read_case();
225 if(build())
226 {
227 if(!check()) printf("No euler circuit exist\n");
228 else
229 {
230 rebuild();
231 output();
232 }
233 }
234 else printf("No euler circuit exist\n");
235 }
236 int main()
237 {
238 int T;
239 scanf("%d",&T);
240 for(int i=0;i<T;i++)
241 {
242 if(i)
243 printf("\n");
244 solve();
245 }
246 return 0;
247 }
人生就像心电图,想要一帆风顺,除非game-over


浙公网安备 33010602011771号