[POJ1637]混合图的欧拉回路判定|网络流
混合图的欧拉回路判定
上一篇正好分别讲了有向图和无向图的欧拉回路判定方法
如果遇上了混合图要怎么做呢?
首先我们思考有向图的判定方法:所有点的出度=入度
我们可以先为无向边任意定一个向,算出此时所有顶点的入度和出度
对于一个入度<>出度的点,我们修改与它相连的一条无向边的方向,一种可能是入度-1出度+1,一种可能是入度+1出度-1
无论如何不会改变的是其入度与出度的差一直是偶数
所以首先我们对任意定向后的整张图根据其入度与出度之差进行初步判定
有顶点入度与出度之差为奇数的图一定无法构成欧拉回路
接下来继续看,对于每一条任意定向的无向边:

我们改变了方向之后可以将a[u]-b[u]的差增加2,将a[v]-b[v]的差减小2
我们可以根据a[i]与b[i]的差计算出要使a[i]=b[i]时需要几条原来从a[i]出发的边反向
同时要考虑到a[i]也可能作为原来作为终点
我们可以据此建立起网络流的模型
建立一个源点s和一个汇点t
对于所有a[i]>b[i]的点,从s到i建立一条容量为c=(a[i]-b[i]) >> 1的边(如果这些流量都流完了,点i的出入度就相同了
我们期望流过c流量的边,我们希望通过c条原本起点为i的边反转从而达到这样的目的
同样的,对于所有a[i]<b[i]的点,从i到t建立一条容量为(b[i]-a[i]) >> 1的边(如果这些流量流完了,点i的出入度就相同了
我们期望流过c流量的边,通过c条原本终点为i的边反转
当然不排除尽管位于左侧但仍然要作为终点的情况,这个时候增加的a[i]-b[i]的差我们要通过更多原本以i为起点的边反转
网络流正好满足这个性质,从其他点流过来的流量我们需要推出去更多的流量
所以对于原本定向为(x,y)的边,我们从x到y连一条流量为1的边
为了优化这个操作,使边数更小,我们可以累计x到y的边,最后加边
这里思考一下为什么不能将每条边当做的流量乘二,与源点汇点的流量不用除以2
这就防止了一条边被拆做两个半条用的情况
至于怎样才算成功,即所有从源点发出去的流量=留回汇点的流量
附上原题描述以及代码
Sightseeing tour
Description
The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visited exactly once. The bus should also start and end at the same junction. As in any city, the streets are either one-way or two-way, traffic rules that must be obeyed by the tour bus. Help the executive board and determine if it's possible to construct a sightseeing tour under these constraints.program poj1637;
const maxn=;maxm=;
var fa,next,w,rec:array[-..maxm]of longint;
opt,link,dis,a,b:array[-..maxn]of longint;
t,test,n,m,ans,j,s,tt,i:longint;
e:array[-..maxm]of record x,y,z:longint;end;
c:array[-..maxn,-..maxn]of longint; function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end; procedure add(x,y,z:longint);
begin
inc(j);fa[j]:=y;next[j]:=link[x];link[x]:=j;w[j]:=z;rec[j]:=j+;
inc(j);fa[j]:=x;next[j]:=link[y];link[y]:=j;w[j]:=;rec[j]:=j-;
end; function spfa:boolean;
var head,tail,x,j:longint;
begin
fillchar(dis,sizeof(dis),);
head:=;tail:=;opt[]:=s;dis[s]:=;
while head<>tail do
begin
head:=(head+)mod maxn;
x:=opt[head];j:=link[x];
while j<> do
begin
if (dis[x]+<dis[fa[j]])and(w[j]>) then
begin
dis[fa[j]]:=dis[x]+;
tail:=(tail+) mod maxn;opt[tail]:=fa[j];
end;
j:=next[j];
end;
end;
if dis[t]<>dis[-] then exit(true) else exit(false);
end; function dfs(p,sum:longint):longint;
var j,tem,x:longint;
begin
tem:=;
if p=t then exit(sum);
j:=link[p];
while j<> do
begin
if (dis[fa[j]]=dis[p]+)and(w[j]>) then
begin
x:=dfs(fa[j],min(sum-tem,w[j]));
inc(tem,x);dec(w[j],x);inc(w[rec[j]],x);
if tem=sum then exit(sum);
end;
j:=next[j];
end;
exit(tem);
end; function check:boolean;
var i,k:longint;
begin
j:=;s:=;t:=n+;ans:=;
fillchar(c,sizeof(c),);
for i:= to n do if odd(abs(a[i]-b[i])) then exit(false);
for i:= to m do if e[i].z= then inc(c[e[i].x,e[i].y]);
for i:= to n do if a[i]-b[i]> then
begin
add(s,i,(a[i]-b[i]) >> );
inc(ans,(a[i]-b[i]) >> );
end
else
if b[i]-a[i]> then add(i,t,(b[i]-a[i]) >> );
for i:= to n do
for k:= to n do if c[i,k]> then add(i,k,c[i,k]);
while (spfa)and(ans>) do
dec(ans,dfs(s,ans));
if ans= then exit(true) else exit(false);
end; begin
readln(test);
for tt:= to test do
begin
readln(n,m);
fillchar(link,sizeof(link),);
fillchar(next,sizeof(next),);
for i:= to n do
begin
a[i]:=;b[i]:=;
end;
for i:= to m do
begin
readln(e[i].x,e[i].y,e[i].z);
inc(a[e[i].x]);inc(b[e[i].y]);
end;
if check then writeln('possible') else writeln('impossible');
end;
end.
[POJ1637]混合图的欧拉回路判定|网络流的更多相关文章
- ACM/ICPC 之 混合图的欧拉回路判定-网络流(POJ1637)
//网络流判定混合图欧拉回路 //通过网络流使得各点的出入度相同则possible,否则impossible //残留网络的权值为可改变方向的次数,即n个双向边则有n次 //Time:157Ms Me ...
- POJ 1637 混合图的欧拉回路判定
题意:一张混合图,判断是否存在欧拉回路. 分析参考: 混合图(既有有向边又有无向边的图)中欧拉环.欧拉路径的判定需要借助网络流! (1)欧拉环的判定:一开始当然是判断原图的基图是否连通,若不连通则一定 ...
- 算法复习——欧拉回路混合图(bzoj2095二分+网络流)
题目: Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车 ...
- bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)
传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路 ...
- 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)
这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...
- POJ1637:Sightseeing tour(混合图的欧拉回路)
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10581 Accepted: 4466 ...
- POJ 1637 Sightseeing tour (混合图欧拉路判定)
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6986 Accepted: 2901 ...
- UVa 10735 (混合图的欧拉回路) Euler Circuit
题意: 给出一个图,有的边是有向边,有的是无向边.试找出一条欧拉回路. 分析: 按照往常的思维,遇到混合图,我们一般会把无向边拆成两条方向相反的有向边. 但是在这里却行不通了,因为拆成两条有向边的话, ...
- UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)
题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制 ...
随机推荐
- VS2010安装MVC3出错
开始已经在电脑上安装了VS2010以及SP1,还装了MVC4的相关升级包.最后项目中又要用MVC3,然后又去安装MVC3的安装包,但是在安装的过程就出现了问题.一直安装不成功,最后在 ...
- Spring常用注解用法总结
转自http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Dispat ...
- React Antd中样式的修改
如果需要对antd的样式进行修改, 进入你要修改的页面 注意:不能直接在自己的文件下面,加入一个css,修改这个class的样式,应该 加入global限定,global {} , 在{}里面写入 . ...
- 2016弱校联盟十一专场10.3 We don't wanna work!
能把 not working now 写成 not working hard now 还查一晚上也是没谁了 我的做法是维护两个set 分别是前20% 和后80% #include<iostrea ...
- CCF-NOIP-2018 提高组(复赛) 模拟试题(五)
T1 相遇 [问题描述] 在一场奇怪的梦里,小 Y 来到了一个神奇的国度.这个国度可以用一根数轴表示,小 Y 在 N 处,而小 Y 想吃的美食在 K 处.小 Y 有两种方式移动, 一种叫做步行, 一种 ...
- (转)简述47种Shader Map的渲染原理与制作方法
在Shader中会使用各种不同图参与渲染,所以简单地总结下各种图的渲染原理.制作方法,最后面几种是程序生成图. 1. Albedo 2. Diffuse(Photographic) 从上图可以看出来, ...
- HDFS伪分布式
(一).HDFS shell操作 以上已经介绍了如何搭建伪分布式的Hadoop,既然环境已经搭建起来了,那要怎么去操作呢?这就是本节将要介绍的内容: HDFS自带有一些shell命令,通过这些命令我们 ...
- for循环再探
摘要:for循环头的组成.for的执行流程 一.for 语句的组成 0. 举个例子 for (int val = 1; val <= 10; ++val) sum += val; 1. 循环头的 ...
- org.json.Json Object的put和append方法比较
json.append(key,value) 会把 value 包装成一个数组 JSONObject append = new JSONObject().append("a", & ...
- libevent显式调用事件处理
) { SearchAcceptListen2(p_ev_arg->listen_fd,,¬ify_event,base); event_base_loop(base, EVLOO ...