POJ 1637 混合图的欧拉回路 网络流
来源:互联网 发布:中兴软创 知乎 编辑:程序博客网 时间:2024/05/16 01:52
题目链接:http://poj.org/problem?id=1637
题意:就是判断一个混合图是否有欧拉回路
解法:
其实,难点在于图中的无向边,需要对所有的无向边定向(指定一个方向,使之变为有向边),使整个图变成
一个有向欧拉图(或有向半欧拉图)。若存在一个定向满足此条件,则原图是欧拉图(或半欧拉图)否则不
是。关键就是如何定向?
首先给原图中的每条无向边随便指定一个方向(称为初始定向),将原图改为有向图G’,然后的任务就是改变
G’中某些边的方向(当然是无向边转化来的,原混合图中的有向边不能动)使其满足每个点的入度等于出度。
设D[i]为G’中(点i的出度 - 点i的入度)。可以发现,在改变G’中边的方向的过程中,任何点的D值的奇偶性都
不会发生改变(设将边(i, j)改为(j, i),则i入度加1出度减1,j入度减1出度加1,两者之差加2或减2,奇偶性
不变)!而最终要求的是每个点的入度等于出度,即每个点的D值都为0,是偶数,故可得:若初始定向得到
的G’中任意一个点的D值是奇数,那么原图中一定不存在欧拉环!
若初始D值都是偶数,则将G’改装成网络:设立源点S和汇点T,对于每个D[i]>0的点i,连边(S, i),容量为
D[i]/2;对于每个D[j]小于0的点j,连边(j, T),容量为-D[j]/2;G’中的每条边在网络中仍保留,容量为1(表示
该边最多只能被改变方向一次)。求这个网络的最大流,若S引出的所有边均满流,则原混合图是欧拉图,将
网络中所有流量为1的中间边(就是不与S或T关联的边)在G’中改变方向,形成的新图G”一定是有向欧拉图;
若S引出的边中有的没有满流,则原混合图不是欧拉图。
证明的话见邝斌巨苣的博客:
http://www.cnblogs.com/kuangbin/p/3537525.html orz
就这个题本身而言,知道如何建图判定就可以了,证明感觉不是太重要,这是对我这种一向不会证明的我人来
说QAQ
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1010;const int maxm = 510010;const int inf = 0x3f3f3f3f;struct G{ int v, cap, next; G() {} G(int v, int cap, int next) : v(v), cap(cap), next(next) {}} E[maxm];int p[maxn], T;int d[maxn], temp_p[maxn], qw[maxn]; //d顶点到源点的距离标号,temp_p当前狐优化,qw队列void init(){ memset(p, -1, sizeof(p)); T = 0;}void add(int u, int v, int cap){ E[T] = G(v, cap, p[u]); p[u] = T++; E[T] = G(u, 0, p[v]); p[v] = T++;}bool bfs(int st, int en, int n){ int i, u, v, head, tail; for(i = 0; i <= n; i++) d[i] = -1; head = tail = 0; d[st] = 0; qw[tail] = st; while(head <= tail) { u = qw[head++]; for(i = p[u]; i + 1; i = E[i].next) { v = E[i].v; if(d[v] == -1 && E[i].cap > 0) { d[v] = d[u] + 1; qw[++tail] = v; } } } return (d[en] != -1);}int dfs(int u, int en, int f){ if(u == en || f == 0) return f; int flow = 0, temp; for(; temp_p[u] + 1; temp_p[u] = E[temp_p[u]].next) { G& e = E[temp_p[u]]; if(d[u] + 1 == d[e.v]) { temp = dfs(e.v, en, min(f, e.cap)); if(temp > 0) { e.cap -= temp; E[temp_p[u] ^ 1].cap += temp; flow += temp; f -= temp; if(f == 0) break; } } } return flow;}int dinic(int st, int en, int n){ int i, ans = 0; while(bfs(st, en, n)) { for(i = 0; i <= n; i++) temp_p[i] = p[i]; ans += dfs(st, en, inf); } return ans;}int in[maxn], out[maxn];int main(){ int T, n, m; scanf("%d", &T); while(T--){ scanf("%d%d", &n,&m); init(); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); while(m--){ int u, v, w; scanf("%d%d%d", &u,&v,&w); in[v]++, out[u]++; if(w == 0) add(u, v, 1); } bool flag = 1; for(int i = 1; i<= n; i++){ int D = in[i]-out[i]; if(D%2){ flag = 0; break; } if(D<0){ D = -D; add(0, i, D/2); } else{ add(i, n+1, D/2); } } if(flag==0){ printf("impossible\n"); continue; } dinic(0, n+1, n+2); for(int i = p[0]; ~i; i = E[i].next){ if(E[i].cap){ flag = 0; break; } } if(flag) printf("possible\n"); else printf("impossible\n"); } return 0;}
- POJ 1637 混合图的欧拉回路 网络流
- poj 1637(求混合图的欧拉回路是否存在:构造网络流求解)
- POJ-1637 Sightseeing tour(通过网络流判定混合图的欧拉回路)
- POJ 1637 Sightseeing tour(混合欧拉回路,网络流)
- 混合图的欧拉回路 POJ 1637
- poj 1637 & zoj 1992 混合图的欧拉回路
- POJ 1637 混合图的欧拉回路
- POJ 1637 Sightseeing tour (混合图的欧拉回路)
- poj 1637 求混合图的欧拉回路
- POJ 1637 混合图的欧拉回路
- poj 1637 混合图的欧拉回路
- POJ 1637 Sightseeing tour(混合图的欧拉回路)
- POJ 1637 Sightseeing tour 混合图的欧拉回路
- poj 1637 Sightseeing tour 混合图的欧拉回路
- 网络流之--混合图的欧拉回路
- poj 1637 混合欧拉回路 网络流 dinic 以及sap 算法
- poj 1637 Sightseeing tour 【网络流 求解混合欧拉回路是否存在】
- POJ 1637 网络流判混合欧拉回路 解题报告
- Linux 查看系统相关信息
- 【转载】了解快速公交回想大连感想三——个人感觉大连公共交通快速体系的发展之路
- jquery tree
- win7 待机后没有声音解决方法
- ui的一些认识
- POJ 1637 混合图的欧拉回路 网络流
- Hello World!
- NYOJ--21--bfs--三个水杯
- jsp dialog 对话框
- 【转】谷歌知多少?
- list<object> 与List<Sting[]>打回前台
- ajax获取返回值两种方式
- jQuery
- js jsp 数据交互