POJ1637 Sightseeing tour(判定混合图欧拉回路)
有向连通图存在欧拉回路的充要条件是所有点入度=出度。
首先随便给定所有无向边一个方向(不妨直接是u->v方向),记录所有点的度(记:度=入度-出度)。
这时如果有点的度不等于0,那么就不存在欧拉回路,就需要改变那些无向边的方向。
而改变一个无向边的方向,相当于边上两个端点的入度和出度都变化了1,它们的度±2。
另外,这样可以证明如果这时某个点的度为奇数那么一定不存在存在欧拉回路的解。
构图如下:所有无向边(u,v),建立容量为1的(u,v)边;所有度小于0的点u,建立容量为-deg/2的(vs,u)边;所有度大于0的点u,建立容量为deg/2(u,vt)边。
最后如果和vs、vt关联的边都满流,那么就有存在欧拉回路的解。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 222 8 #define MAXM 4444 9 10 struct Edge{ 11 int v,cap,flow,next; 12 }edge[MAXM]; 13 int vs,vt,NE,NV; 14 int head[MAXN]; 15 16 void addEdge(int u,int v,int cap){ 17 edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0; 18 edge[NE].next=head[u]; head[u]=NE++; 19 edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0; 20 edge[NE].next=head[v]; head[v]=NE++; 21 } 22 23 int level[MAXN]; 24 int gap[MAXN]; 25 void bfs(){ 26 memset(level,-1,sizeof(level)); 27 memset(gap,0,sizeof(gap)); 28 level[vt]=0; 29 gap[level[vt]]++; 30 queue<int> que; 31 que.push(vt); 32 while(!que.empty()){ 33 int u=que.front(); que.pop(); 34 for(int i=head[u]; i!=-1; i=edge[i].next){ 35 int v=edge[i].v; 36 if(level[v]!=-1) continue; 37 level[v]=level[u]+1; 38 gap[level[v]]++; 39 que.push(v); 40 } 41 } 42 } 43 44 int pre[MAXN]; 45 int cur[MAXN]; 46 int ISAP(){ 47 bfs(); 48 memset(pre,-1,sizeof(pre)); 49 memcpy(cur,head,sizeof(head)); 50 int u=pre[vs]=vs,flow=0,aug=INF; 51 gap[0]=NV; 52 while(level[vs]<NV){ 53 bool flag=false; 54 for(int &i=cur[u]; i!=-1; i=edge[i].next){ 55 int v=edge[i].v; 56 if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){ 57 flag=true; 58 pre[v]=u; 59 u=v; 60 //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap)); 61 aug=min(aug,edge[i].cap-edge[i].flow); 62 if(v==vt){ 63 flow+=aug; 64 for(u=pre[v]; v!=vs; v=u,u=pre[u]){ 65 edge[cur[u]].flow+=aug; 66 edge[cur[u]^1].flow-=aug; 67 } 68 //aug=-1; 69 aug=INF; 70 } 71 break; 72 } 73 } 74 if(flag) continue; 75 int minlevel=NV; 76 for(int i=head[u]; i!=-1; i=edge[i].next){ 77 int v=edge[i].v; 78 if(edge[i].cap!=edge[i].flow && level[v]<minlevel){ 79 minlevel=level[v]; 80 cur[u]=i; 81 } 82 } 83 if(--gap[level[u]]==0) break; 84 level[u]=minlevel+1; 85 gap[level[u]]++; 86 u=pre[u]; 87 } 88 return flow; 89 } 90 91 int n,m,deg[MAXN]; 92 bool solve(){ 93 for(int i=1; i<=n; ++i){ 94 if(abs(deg[i])&1) return 0; 95 if(deg[i]>0) addEdge(i,vt,deg[i]>>1); 96 else if(deg[i]<0) addEdge(vs,i,(-deg[i])>>1); 97 } 98 ISAP(); 99 for(int i=0; i<NE ;i+=2){ 100 if(edge[i^1].v!=vs&&edge[i].v!=vt) continue; 101 if(edge[i].cap!=edge[i].flow) return 0; 102 } 103 return 1; 104 } 105 int main(){ 106 int t,a,b,c; 107 scanf("%d",&t); 108 while(t--){ 109 scanf("%d%d",&n,&m); 110 vs=0; vt=n+1; NV=vt+1; NE=0; 111 memset(head,-1,sizeof(head)); 112 memset(deg,0,sizeof(deg)); 113 while(m--){ 114 scanf("%d%d%d",&a,&b,&c); 115 --deg[a]; ++deg[b]; 116 if(c==0) addEdge(a,b,1); 117 } 118 if(solve()) puts("possible"); 119 else puts("impossible"); 120 } 121 return 0; 122 }
转载于:https://www.cnblogs.com/WABoss/p/4851919.html
POJ1637 Sightseeing tour(判定混合图欧拉回路)相关推荐
- POJ - 1637 Sightseeing tour(混合图欧拉回路的求解--建图跑最大流)
题目链接:https://vjudge.net/contest/399194#problem/B The city executive board in Lund wants to construct ...
- 2095: [Poi2010]Bridges 二分+混合图欧拉回路(网络流)
好厉害的题啊QAQ,并不会做. 最大值最小想到是二分,然后就是一个混合图欧拉回路的问题. 混合图欧拉回路问题的解决: 我们首先想到有向图的欧拉回路,需满足的条件是每个点的入度等于出度.那么对于一个混合 ...
- BZOJ2095 POI2010 Bridges 【二分+混合图欧拉回路】
BZOJ2095 POI2010 Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛 ...
- TZOJ 2099 Sightseeing tour(网络流判混合图欧拉回路)
描述 The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that to ...
- BZOJ 2095 [Poi2010]Bridges 二分 最大流(混合图欧拉回路)
题目大意:给出一张n个点m条边的联通图,无重边,每条边有正反两个权值.现要从点1出发经过每条边每个点一次,问最大边权最小是多少. 最大最小容易想到二分,问题是如何判断是否有欧拉回路. 图不连通自然没有 ...
- [BZOJ2095][Poi2010]Bridges 最大流(混合图欧拉回路)
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海, ...
- Bzoj2095:[Poi2010]Bridges:混合图欧拉回路,网络流
题目链接:2095:[Poi2010]Bridges 二分答案建图后显然是混合图的欧拉回路,有向边删掉无向边随机定向计算入度-出度的差du[i],如果du[i]<0连边(i,T,-du[i]/2 ...
- POJ 1637 Sightseeing tour 混合图欧拉回路存在性判断
没有想到网络流还能解决这一类问题,完全想不到@_@ 一开始把所有的无向边制定任意方向有当做有向边看,然后统计每个点的入度和出度.以前有向图的欧拉回路判定是每个点的入读都等于出度,这样可以保证可以回到起 ...
- BZOJ 2095: [Poi2010]Bridges 混合图欧拉回路
YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1出发,骑过每一座桥,到达 ...
最新文章
- 从ASP.NET得到Microsoft Word文档
- Bit-Z转入GXS、PPS、SPHTX、EOS未到账解决方案
- MongoDB缓存技术总结
- Perl的特殊变量汇总
- IPC Binder
- 通过掌握谷歌成为更好的程序员
- java堆排序工具包_JAVA 排序工具类
- 用python编计算器_python编计算器
- Python安装shapely包出现WindowsError: [Error 126]解决方案
- 嵌入式系统开发笔记88:认识51微控制器系统架构
- 一款Excel导入导出解决方案组成的轻量级开源组件
- RediSearch一个媲美es的全文搜索引擎
- 解决p标签自动换行文字两端不对齐问题
- 锁定表格栏位范例网页
- Kaggle鱼品种识别
- 英文文章汇总+翻译小亮点
- 【Datawhale可解释性机器学习笔记】预备知识学习
- 二陈丸配什么吃不上火_什么样的人群不适合吃二陈丸?
- 论企业IT信息化与企业文化的关系
- 基于wampsever的学生成绩管理系统的开发教程
热门文章
- 基于朴素贝叶斯分类器的西瓜数据集 2.0 预测分类_第十章:利用Python实现朴素贝叶斯模型
- BIRCH算法(Java实现)
- 互联网世界的“人工智能”——探秘“深度学习”的前世今生
- php常用设计模式和算法,常用算法、问答、设计模式
- VB.NET 读写HTML 文件,VB.NET 简单介绍文件的读写----流类
- C陷阱与缺陷阅读笔记(下)
- python为什么会出现无响应怎么办_python定时检测无响应进程并重启的实例代码
- SparkStreaming DStream入门及其算子应用
- 设计模式的征途—23.解释器(Interpreter)模式
- 使用JavaScript实现长方形、直角三角形、平行四边形、等腰三角形、倒三角、数字三角形...