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 }
View Code

 

posted @ 2015-09-06 21:47  一麻袋码的玛侬  阅读(196)  评论(0)    收藏  举报