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 ...
随机推荐
- SharePoint Error - An unrecognized HTTP response was received when attempting to crawl this item
SharePoint 2013爬网报错 An unrecognized HTTP response was received when attempting to crawl this item. V ...
- Atitit.在线充值功能的设计
Atitit.在线充值功能的设计 1. 流程1 2. Js sdk api 增加订单1 3. Java api 返回servlet处理1 3.1. 返回网址的本地host测试2 1. 流程 本地增 ...
- [Android L]SEAndroid开放设备文件结点权限(读或写)方法(涵盖常用操作:sys/xxx、proc/xxx、SystemProperties)
温馨提示 建议你先了解一下上一篇博文([Android L]SEAndroid增强Androd安全性背景概要及带来的影响)所讲的内容,先对SEAndroid窥个全貌,然后再继续本节内容. ...
- 深入.net(数据类型)
C#究竟为我们提供了哪些“数据类型”供我们使用?这些类型有什么样的“特征”? 数据类型的分类: --- 数据类型是存放数据的容器.那么我们就以它们“存放数据的方式”分类! 1.值类型:变量中直接存放着 ...
- git之一
1.Git是什么Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 ...
- Java开发人员最常犯的10个错误
这个列表总结了10个Java开发人员最常犯的错误. Array转ArrayList 当需要把Array转成ArrayList的时候,开发人员经常这样做: List<String> list ...
- openstack security group and rules python api use
nova和neutron都可以,但是感觉还是用neutron好. import neutronclient.v2_0.client as neclient neutron = neclient.Cli ...
- MVC 多语言记录1 设置默认的ResourceType
http://stackoverflow.com/questions/3260748/default-resource-for-data-annotations-in-asp-net-mvc Add ...
- SQL Server:“数据收缩”详解
1. 数据库的相关属性 在MS中创建数据库时会为数据库分配初始的大小(如下图:数据库和日志两个文件),随着数据库的使用文件会逐渐增大.数据库文件大小的增加有两种方式: 自动增长:在自动增长中可以设置每 ...
- 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...