UVA 10735 Euler Circuit
2013-08-09 17:39
267 查看
大意 混合图中找欧拉回路
思路 混合图中判断是否存在欧拉回路的方法都是一样,只是如何去找欧拉回路的问题。
如何去找欧拉回路,满流后,如果图中已给出的无向边(e.cap > 0)有流流过,则把该边反向,如果没有,则不改,然后用套圈算法去找欧拉回路。
思路 混合图中判断是否存在欧拉回路的方法都是一样,只是如何去找欧拉回路的问题。
如何去找欧拉回路,满流后,如果图中已给出的无向边(e.cap > 0)有流流过,则把该边反向,如果没有,则不改,然后用套圈算法去找欧拉回路。
/*UVA 10735*/ #include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <algorithm> #include <map> using namespace std; const int maxn = 110; const int maxm = 110*110; const int INF = 0x3f3f3f3f; struct Edge { int from, to, cap, flow; Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {} }; struct Dinic { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n) { this->n = n; for(int i = 0; i <= n; i++) G[i].clear(); edges.clear(); } void ClearFlow () { for(int i = 0; i < edges.size(); i++) edges[i].flow = 0; } void AddEdge(int from, int to, int cap) { edges.push_back(Edge (from, to, cap, 0)); edges.push_back(Edge (to, from, 0, 0)); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); d[s] = 0; vis[s] = 1; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(!vis[e.to] && e.cap > e.flow) { vis[e.to] = 1; d[e.to] = d[x]+1; Q.push(e.to); } } } return vis[t]; } int DFS(int x, int a) { if(x == t || a == 0) return a; int flow = 0, f; for(int &i = cur[x]; i < G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int Maxflow(int s, int t) { this->s = s; this->t = t; int flow = 0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } }; void readint(int &x) { char c; while(!isdigit(c)) c = getchar(); x = 0; while(isdigit(c)) { x = x*10 + c-'0'; c = getchar(); } } void writeint(int x) { if(x > 9) writeint(x/10); putchar(x%10+'0'); } int fa[maxn]; int find(int x) { return x == fa[x]? x : fa[x] = find(fa[x]); } void Union(int x, int y) {x = find(x), y = find(y); if(x != y) fa[x] = y; } ////////////////////// Dinic solver; int n, m, s, t; int ind[maxn], outd[maxn]; bool vis[maxn]; struct Edge2 { int v; bool vis; int next; }edge[maxm]; int cnt; int first[maxn]; void read_graph(int u, int v) { edge[cnt].v = v, edge[cnt].vis = 0; edge[cnt].next = first[u], first[u] = cnt++; } void init() { cnt = 0; memset(first, -1, sizeof(first)); memset(ind, 0, sizeof(ind)); memset(outd, 0, sizeof(outd)); memset(vis, 0, sizeof(vis)); for(int i = 0; i <= n+2; i++) fa[i] = i; } void read_case() { readint(n), readint(m); init(); solver.init(n+5); while(m--) { int x, y; char c; scanf("%d %d %c", &x, &y, &c); if(c == 'D') read_graph(x, y); else if(c == 'U') solver.AddEdge(x, y, 1); vis[x] = vis[y] = 1; outd[x]++, ind[y]++; Union(x, y); } } int totflow; int build() { s = 0, t = n+1; totflow = 0; for(int i = 1; i <= n; i++) if(vis[i]) { if((outd[i]+ind[i]) & 1) return 0; else if(outd[i] > ind[i]) { int d = outd[i]-ind[i]; solver.AddEdge(s, i, d/2); totflow += d/2; } else if(ind[i] > outd[i]) { int d = ind[i]-outd[i]; solver.AddEdge(i, t, d/2); } } return 1; } int check() { int count = 0; for(int i = 1; i <= n; i++) if(vis[i] && fa[i] == i) count++; if(count > 1) return 0; int ans = solver.Maxflow(s, t); if(ans >= totflow) return 1; return 0; } vector<int> ans; int Euler(int u) //套圈算法 { for(int e = first[u]; e != -1; e = edge[e].next) { if(edge[e].vis) continue; edge[e].vis = 1; Euler(edge[e].v); ans.push_back(edge[e].v); } } void rebuild() { for(int i = 0; i < solver.edges.size(); i++) { Edge &e = solver.edges[i]; if(e.cap > 0 && e.from >= 1 && e.from <= n) //已存在的边,e.cap > 0 { if(e.flow == 0) read_graph(e.from, e.to); else read_graph(e.to, e.from); } } } void output() { ans.clear(); Euler(1); printf("1"); for(int i = ans.size()-1; i >= 0; i--) printf(" %d", ans[i]); printf("\n"); } void solve() { read_case(); if(build()) { if(!check()) printf("No euler circuit exist\n"); else { rebuild(); output(); } } else printf("No euler circuit exist\n"); } int main() { int T, times = 0;; for(readint(T); T > 0; T--) { if(times++) printf("\n"); solve(); } return 0; }
相关文章推荐
- UVa 10735 Euler Circuit
- Uva-10735-Euler Circuit
- UVa 10735 (混合图的欧拉回路) Euler Circuit
- (intermediate) 混合图欧拉回路 UVA 10735 - Euler Circuit
- poj 1637判定混合图欧拉回路 uva10735 混合欧拉回路+路径输出
- UVA10735 Euler Circuit题解
- UVA-10735 - Euler Circuit(混合欧拉回路输出)
- uva 10735 混合图欧拉路径的判定,方案输出。
- UVA 10735 混合图的欧拉回路+输出路径
- UVA10735 混合图欧拉回路
- UVA 10735 Euler Circuit (最大流)
- UVA 10735 最大流 混合欧拉回路 输出路径
- 最大流,欧拉回路(混合图的欧拉回路,uva 10735)
- UVA 10735 最大流 混合欧拉回路 输出路径
- 【UVa】 10735 Euler Circuit 混合图的欧拉回路 最大流
- UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)
- UVA 10735 混合图的欧拉回路
- UVALive 4987 Insults
- uva 11205 The Broken Pedometer
- uva131 Time limit exceeded