UVA 10735 最大流 混合欧拉回路 输出路径
来源:互联网 发布:windows选择操作系统 编辑:程序博客网 时间:2024/06/16 02:49
题意:
给你一个图,有N个点,M条边,有单向边和双向边
让你是否存在欧拉回路,有就输出路径
1.判断是否有欧拉回路: 可以用最大流来判断
首先,我们从结论出发: 存在欧拉回路的充要条件是 每个点的入度等于出度。
先把所用无向边随便定向(我们就按输入的时候的方向定向),
问题就转化成 “改变其中一些无向边的方向,使所有的点入度等于出度”。
对于改变某一条无向边, 这条边所在的点的度数改变2(可能-2, 可能+2)。
所以有如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路(情况1)
记出入度之差为d
接下来讨论除情况1以外的情况:
现在,每个点入度和出度之差均为偶数。
对于每个点,我们需要改变跟该点相连的x/2条边, 就可以使该点的入度等于出度
新建源点S和汇点T
对于d < 0 的点i, 连S---->i , 流量为-d
对于d > 0 的点i, 连i----->T,流量为d
对于每条无向边<i,j> ,连i----->j, 流量为2
流一遍最大流,如果对于所有的点i,存在S----->i的边并且漫流,那么欧拉回路就有解。
2.输出欧拉回路: dfs+栈保存
通过最大流以后,我们检查无向边<i,j> 流过的流量,我们可以确定无向边<i,j> 的方向
然后问题就变为 "输出有向图的欧拉回路"。
我们用dfs搜索,访问每条边,对于节点u,当其u以下的儿子节点都搜过时,我们把u入栈
把栈反向输出,就是我们要的欧拉回路。
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <stack>using namespace std;#define PII pair<int, int>#define MP make_pair#define X first#define Y secondconst int maxn = 510;const int inf = 1e9;struct Edge {int v, next, c, op;} edge[maxn * maxn << 1];int E, head[maxn];int n, m;int S, T;vector<PII> edges[maxn];void add(int s, int t, int c) {edge[E].v = t;edge[E].c = c;edge[E].op = 1;edge[E].next = head[s];head[s] = E++;edge[E].v = s;edge[E].c = 0;edge[E].op = 0;edge[E].next = head[t];head[t] = E++;}int st[maxn], top;void init() {E = 0;memset(head, -1, sizeof(head));}int gap[maxn], dis[maxn], pre[maxn], cur[maxn];int sap(int s, int t, int n) // s 源点,t汇点,n顶点总数 { int i; for(i = 0; i <= n; i++) { dis[i] = gap[i] = 0; cur[i] = head[i]; } gap[0] = n; int u = pre[s] = s, maxf = 0, aug = inf, v; while(dis[s] < n) { loop: for(i = cur[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].c > 0 && dis[u] == dis[v] + 1) { aug = min(aug, edge[i].c); pre[v] = u; cur[u] = i; u = v; if(u == t) { while(u != s) { u = pre[u]; edge[cur[u]].c -= aug; edge[cur[u] ^ 1].c += aug; } maxf += aug; aug = inf; } goto loop; } } int min_d = n; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].c > 0 && dis[v] < min_d) { min_d = dis[v]; cur[u] = i; } } if(!(--gap[dis[u]])) break; ++gap[dis[u] = min_d + 1]; u = pre[u]; } return maxf;}char buf[3];int d[103];int x, y;bool vis[maxn];void dfs(int u) {int i;for (i = 0; i < (int) edges[u].size(); i++) {int v = edges[u][i].X;int id = edges[u][i].Y;if (vis[id])continue;vis[id] = 1;dfs(v);}st[top++] = u + 1;}int id;int main() {int i, j, cas;scanf("%d", &cas);while (cas--) {init();scanf("%d%d", &n, &m);for (i = 0; i < n; i++) {d[i] = 0;edges[i].clear();}top = 0;memset(vis, 0, sizeof(vis));id = 0;for (i = 0; i < m; i++) {scanf("%d%d%s", &x, &y, buf);d[--x]--;d[--y]++;if (buf[0] == 'U') {add(x, y, 2);} else {edges[x].push_back(MP(y, id++));}}for (i = 0; i < n; i++)if (d[i] & 1)break;if (i != n) {puts("No euler circuit exist\n");continue;}S = n;T = n + 1;for (i = 0; i < n; i++) {if (d[i] < 0)add(S, i, -d[i]);else if (d[i] > 0)add(i, T, d[i]);}int sum = sap(S, T, T + 1);for (i = head[S]; ~i; i = edge[i].next)if (edge[i].c)break;if (~i) {puts("No euler circuit exist\n");continue;}for (i = 0; i < n; i++)for (j = head[i]; ~j; j = edge[j].next)if (edge[j].op) {int v = edge[j].v;if (v >= n)continue;if (edge[j ^ 1].c) {edges[v].push_back(MP(i, id++));} elseedges[i].push_back(MP(v, id++));}dfs(0);for (i = top - 1; i >= 1; i--)printf("%d ", st[i]);printf("%d\n\n", st[0]);}return 0;}
- UVA 10735 最大流 混合欧拉回路 输出路径
- UVA 10735 最大流 混合欧拉回路 输出路径
- UVA 10735 混合图的欧拉回路+输出路径
- 最大流,欧拉回路(混合图的欧拉回路,uva 10735)
- 【UVa】 10735 Euler Circuit 混合图的欧拉回路 最大流
- poj 1637判定混合图欧拉回路 uva10735 混合欧拉回路+路径输出
- UVA 10054 The Necklace(欧拉回路+输出路径)
- UVA 10735 混合图的欧拉回路
- POJ 637 Sightseeing tour 混合欧拉回路 最大流
- 欧拉回路--输出欧拉回路的路径
- 欧拉回路的路径输出——逆序输出 UVA 10054 The Necklace
- 欧拉回路输出路径 POJ
- UVA 10054 无向图的欧拉回路输出路径
- The Necklace UVA - 10054 题解(欧拉回路,路径输出)
- poj1637 Sightseeing tour,混合图的欧拉回路问题,最大流解
- 欧拉路径/回路
- 欧拉回路输出
- 欧拉回路的构建及输出欧拉回路的路径
- hdu1010Tempter of the Bone dfs+奇偶剪枝
- A + B Problem II
- 彻底搞定C指针---指向指针的指针
- Oracle开发过程中用户的权限的创建,解锁,赋权
- POJ1042 Gone Fishing
- UVA 10735 最大流 混合欧拉回路 输出路径
- python文件类型及运行方式
- cannot find the definition (implementation) of this function 解决方法
- HDU-2086
- mysql 添加字段 修改字段为not null
- oracle删除用户命令和部分命令
- servlet跳转页面的几种方法
- HDU-2090
- KMP&&EKMP&&Manacher算法模版