poj1637 Sightseeing tour
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 8859 | Accepted: 3728 |
Description
Input
Output
Sample Input
4
5 8
2 1 0
1 3 0
4 1 1
1 5 0
5 4 1
3 4 0
4 2 1
2 2 0
4 4
1 2 1
2 3 0
3 4 0
1 4 1
3 3
1 2 0
2 3 0
3 2 0
3 4
1 2 0
2 3 1
1 2 0
3 2 0
Sample Output
possible
impossible
impossible
possible
Source
混合欧拉回路,用最大流求解。
【建模方法】
把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度
之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,
也就是总度数为偶数,存在奇数度点必不能有欧拉回路。
好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以2,得x。
也就是说,对于每一个点,只要将x 条边改变方向(入>出就是变入,出>入就是变出),就能保证出=入。如果每个点都是出=入,那么很明显,该图就存在欧拉回路。
现在的问题就变成了:我该改变哪些边,可以让每个点出=入?构造网络流模型。首先,有向边是不能改变方向的,要之无用,删。一开始不是把无向边定向了吗?定的是什么向,就把网络构建成什么样,边长容量上限1。另新建s和t。对于入>出的点u,连接边(u, t)、容量为x,对于出>入的点v,连接边(s, v),容量为x(注意对不同的点x不同)。之后,察看是否有满流的分配。有就是能有欧拉回路,没有就是没有。欧拉回路是哪个?察看流值分配,将所有流量非 0(上限是1,流值不是0就是1)的边反向,就能得到每点入度=出度的欧拉图。
由于是满流,所以每个入>出的点,都有x条边进来,将这些进来的边反向,OK,入=出了。对于出>入的点亦然。那么,没和s、t连接的点怎么办?和s连接的条件是出>入,和t连接的条件是入>出,那么这个既没和s也没和t连接的点,自然早在开始就已经满足入=出了。那么在网络流过程中,这些点属于“中间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反向之后,自然仍保持平衡。
所以,就这样,混合图欧拉回路问题,解了。(来自《网络流建模汇总 by Edelweiss》)
15716369 ksq2013 1637 Accepted 932K 32MS G++ 2812B 2016-07-13 13:18:25
#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f
using namespace std;
int n,m,s,t,ecnt,first[250],nxt[25000],du[250],res;
struct Edge{int u,v,cap,flow;}e[25000];
bool vis[250];
int q[25000],d[250],cur[250],num[250],p[25000];
bool judge()
{
for(int i=1;i<=n;i++)
if(du[i]&1)return false;
return true;
}
void Link(int x,int y,int z)
{
e[++ecnt].u=x,e[ecnt].v=y,e[ecnt].cap=z,e[ecnt].flow=0;
nxt[ecnt]=first[x];
first[x]=ecnt;
e[++ecnt].u=y,e[ecnt].v=x,e[ecnt].cap=0,e[ecnt].flow=0;
nxt[ecnt]=first[y];
first[y]=ecnt;
}
void design()
{
res=0;
for(int i=1;i<=n;i++){
if(du[i]<0)Link(i,t,-du[i]/2);
if(du[i]>0)Link(s,i,du[i]/2),res+=(du[i]/2);
}
}
void bfs()
{
memset(vis,false,sizeof(vis));
int head=0,tail=1;
q[0]=t;d[t]=0;vis[t]=true;
while(head^tail){
int now=q[head++];
for(int i=first[now];i;i=nxt[i])
if(!vis[e[i].u]&&e[i].cap>e[i].flow){
vis[e[i].u]=true;
d[e[i].u]=d[now]+1;
q[tail++]=e[i].u;
}
}
}
int Agument()
{
int x=t,a=INF;
while(x^s){
a=min(a,e[p[x]].cap-e[p[x]].flow);
x=e[p[x]].u;
}
x=t;
while(x^s){
e[p[x]].flow+=a;
e[p[x]^1].flow-=a;
x=e[p[x]].u;
}
return a;
}
int ISAP()
{
int flow=0;
bfs();
memset(num,0,sizeof(num));
for(int i=0;i<=n+1;i++)num[d[i]]++;
int x=s;
for(int i=0;i<=n+1;i++)cur[i]=first[i];
while(d[s]<n+2){
if(!(x^t)){
flow+=Agument();
x=s;
}
bool advanced=false;
for(int i=cur[x];i;i=nxt[i])
if(e[i].cap>e[i].flow&&d[x]==d[e[i].v]+1){
advanced=true;
p[e[i].v]=i;
cur[x]=i;
x=e[i].v;
break;
}
if(!advanced){
int mn=n+1;
for(int i=first[x];i;i=nxt[i])
if(e[i].cap>e[i].flow)
mn=min(mn,d[e[i].v]);
if(--num[d[x]]==0)break;
num[d[x]=mn+1]++;
cur[x]=first[x];
if(x^s)x=e[p[x]].u;
}
}
return flow;
}
int main()
{
int T;
scanf("%d",&T);
for(;T;T--){
scanf("%d%d",&n,&m);
s=0,t=n+1,ecnt=1;
memset(d,0,sizeof(d));
memset(p,0,sizeof(p));
memset(nxt,0,sizeof(nxt));
memset(first,0,sizeof(first));
memset(du,0,sizeof(du));
for(int x,y,z,i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
du[x]++,du[y]--;
if(!z)Link(x,y,1);
}
if(!judge()){puts("impossible");continue;}
design();
int tmp=ISAP();
if(tmp^res)puts("impossible");
else puts("possible");
}
return 0;
}
poj1637 Sightseeing tour的更多相关文章
- POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)
Sightseeing tour Time Limit: 1000MS Me ...
- POJ1637:Sightseeing tour(混合图的欧拉回路)
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 10581 Accepted: 4466 ...
- POJ1637 Sightseeing tour(判定混合图欧拉回路)
有向连通图存在欧拉回路的充要条件是所有点入度=出度. 首先随便给定所有无向边一个方向(不妨直接是u->v方向),记录所有点的度(记:度=入度-出度). 这时如果有点的度不等于0,那么就不存在欧拉 ...
- poj1637 Sightseeing tour 混合图欧拉回路判定
传送门 第一次做这种题, 尽管ac了但是完全不知道为什么这么做. 题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路. 做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个 ...
- poj1637 Sightseeing tour(混合图欧拉回路)
题目链接 题意 给出一个混合图(有无向边,也有有向边),问能否通过确定无向边的方向,使得该图形成欧拉回路. 思路 这是一道混合图欧拉回路的模板题. 一张图要满足有欧拉回路,必须满足每个点的度数为偶数. ...
- poj1637 Sightseeing tour[最大流+欧拉回路]
混合图的欧拉回路定向问题. 顺便瞎说几句,有向图定欧拉回路的充要条件是每个点入度等于出度,并且图联通.无向图的话只要联通无奇点即可. 欧拉路径的确定应该是无向图联通且奇点数0个或2个,有向图忘了,好像 ...
- [POJ1637]Sightseeing tour:混合图欧拉回路
分析 混合图欧拉回路问题. 一个有向图有欧拉回路当且仅当图连通并且对于每个点,入度\(=\)出度. 入度和出度相等可以联想到(我也不知道是怎么联想到的)网络流除了源汇点均满足入流\(=\)出流.于是可 ...
- POJ 1637 Sightseeing tour (混合图欧拉路判定)
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6986 Accepted: 2901 ...
- POJ 1637 Sightseeing tour
Sightseeing tour Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9276 Accepted: 3924 ...
随机推荐
- [Android]Activity跳转传递任意类型的数据、Activity为SingleTask时代替StartActivityForResult的解决方案
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4389674.html 需求:在ActivityA跳转到Acti ...
- django 基于proxy实现用户权限管理
项目中经常会遇到用户权限管理的问题,django adminsite已经提供非常实用的用户权限管理机制.不过有些时候,我们希望根据相关用户属性来过滤adminsite中显示的内容.下文将结束如何实现: ...
- C#复习⑥
C#复习⑥ 2016年6月19日 23:46 Main Interfaces & Delegates 接口和委托 1.接口基本语法 public interface IList : IColl ...
- LAMP配置虚拟目录
1. httpd.conf中添加 Listen 81 2. 1 <VirtualHost 127.0.0.2:81> 2 DocumentRoot E:\ws\2011\DiscuzSp ...
- AngularJS 指令
AngularJS 指令 AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-. ng-app 指令 ng-app 指令定义了 AngularJS 应用程序的 根元素. ng-app 指 ...
- C#八皇后问题 枚举值
记得刚出道的时候, 有考虑怎么面试, 以及可能会遇到的面试题, 有一个人说了一下 八皇后问题, 据说要用 sql 语句写出来, 暂时我 写了一个C#版本的, 经测验,八皇后算法结果为 92种, 这个与 ...
- 深入解析Windows操作系统笔记——CH1概念和术语
1.概念和工具 本章主要介绍Windows操作系统的关键概念和术语 1.概念和工具 1.1操作系统版本 1.2基础概念和术语 1.2.1Windows API 1.2.2 服务.函数和例程 1.2.3 ...
- Java Se :线性表
Java的集合框架分为两个系列,Collection和Map系列.在大学期间,学习数据结构时,好像学习了线性表.非线性表.树,哎,都给忘了.其实,在Collection系列内部又可以分为线性表.集合两 ...
- javascript-简单工厂两种实现方式
简单工厂笔记 两种方式: 第一种:通过实例化对象创建 第二种:通过创建一个新对象然后包装增强其属性和功能来实现 差异性:前一种通过类创建的 对象,如果这些类继承同一个父类,他们父类原型上的方法是可以共 ...
- JavaScript学习笔记–(new关键字)
作用 是创建一个对象实例.这个对象可以是用户自定义的,也可以是一些系统自带的带构造函数的对象. 描述 创建一个对象类型需要创建一个指定了名称和属性的函数:其中这些属性可以指向它本身,也可以指向其他对象 ...