混合图的欧拉回路判定

  上一篇正好分别讲了有向图和无向图的欧拉回路判定方法

  如果遇上了混合图要怎么做呢?

  首先我们思考有向图的判定方法:所有点的出度=入度

  我们可以先为无向边任意定一个向,算出此时所有顶点的入度和出度

  对于一个入度<>出度的点,我们修改与它相连的一条无向边的方向,一种可能是入度-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]混合图的欧拉回路判定|网络流的更多相关文章

  1. ACM/ICPC 之 混合图的欧拉回路判定-网络流(POJ1637)

    //网络流判定混合图欧拉回路 //通过网络流使得各点的出入度相同则possible,否则impossible //残留网络的权值为可改变方向的次数,即n个双向边则有n次 //Time:157Ms Me ...

  2. POJ 1637 混合图的欧拉回路判定

    题意:一张混合图,判断是否存在欧拉回路. 分析参考: 混合图(既有有向边又有无向边的图)中欧拉环.欧拉路径的判定需要借助网络流! (1)欧拉环的判定:一开始当然是判断原图的基图是否连通,若不连通则一定 ...

  3. 算法复习——欧拉回路混合图(bzoj2095二分+网络流)

    题目: Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车 ...

  4. bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)

    传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路 ...

  5. 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)

    这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...

  6. POJ1637:Sightseeing tour(混合图的欧拉回路)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10581   Accepted: 4466 ...

  7. POJ 1637 Sightseeing tour (混合图欧拉路判定)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6986   Accepted: 2901 ...

  8. UVa 10735 (混合图的欧拉回路) Euler Circuit

    题意: 给出一个图,有的边是有向边,有的是无向边.试找出一条欧拉回路. 分析: 按照往常的思维,遇到混合图,我们一般会把无向边拆成两条方向相反的有向边. 但是在这里却行不通了,因为拆成两条有向边的话, ...

  9. UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)

    题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制 ...

随机推荐

  1. This content database has a schema version which is not supported in this farm.

          I want to move the website to another server. The new server has reinstall Sharepoint2013 serv ...

  2. CSS实现简易的轮播图

    <html> <head> <meta charset="UTF-8"> <title></title> <sty ...

  3. lua敏感词过滤

    --过滤敏感词(如果onlyKnowHas为true,表示只想知道是否存在敏感词,不会返回过滤后的敏感词,比如用户注册的时候,我们程序是只想知道用户取的姓名是否包含敏感词的(这样也能提高效率,检测到有 ...

  4. 13-Mysql数据库----权限设置

    权限管理 我们知道我们的最高权限管理者是root用户,它拥有着最高的权限操作.包括select.update.delete.update.grant等操作.那么一般情况在公司之后DBA工程师会创建一个 ...

  5. 孤荷凌寒自学python第七十天学习并实践beautifulsoup对象用法3

    孤荷凌寒自学python第七十天学习并实践beautifulsoup对象用法3 (完整学习过程屏幕记录视频地址在文末) 今天继续学习beautifulsoup对象的属性与方法等内容. 一.今天进一步了 ...

  6. Leetcode 54. Spiral Matrix & 59. Spiral Matrix II

    54. Spiral Matrix [Medium] Description Given a matrix of m x n elements (m rows, n columns), return ...

  7. Mapper的方式总结

    Mapper的方式总结: <mappers> <!-- 通过package元素将会把指定包下面的所有Mapper接口进行注册 --> <package name=&quo ...

  8. lintcode-49-字符大小写排序

    49-字符大小写排序 给定一个只包含字母的字符串,按照先小写字母后大写字母的顺序进行排序. 注意事项 小写字母或者大写字母他们之间不一定要保持在原始字符串中的相对位置. 样例 给出"abAc ...

  9. java课堂第7次笔记

  10. Python执行Linux系统命令的4种方法

    http://www.jb51.net/article/56490.htm (1) os.system 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 复制代码代码如下: system( ...