POJ 1637 Sightseeing tour (混合图欧拉回路)
来源:互联网 发布:开关贴淘宝 编辑:程序博客网 时间:2024/05/01 06:48
建图方法:
把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,
若在奇数度点必不能有欧拉回路。
好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以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连接的点,自然早在开始就已经满足入=出了。那么在网络流过程中,这些点属于“中间点”。我们知道中间点流量不允许有累积的,这样,进去多少就出来多少,反向之后,自然仍保持平衡。
欧拉图的判定:
1.基图连通,====》并查集判定
2.无向图:无奇度顶点
有向图:所有顶点出入度相等 ====》统计判定
#include <iostream>#include<stdio.h>#include<string.h>#include<queue>#include<cmath>using namespace std;const int maxn=200+10;const int maxm=2000+10;const int inf=1e9+7;int m,n,s;struct Edge{ int to,next; int cap;}edge[maxm*2];int head[maxn],size;int dis[maxn];//层次网络的编号值,离汇点的距离int father[maxn];int outd[maxn],ind[maxn];void clear()//链式前向星{ size=0; memset(head,-1,sizeof(head)); memset(ind,0,sizeof(ind)); memset(outd,0,sizeof(outd));}void _add(int from,int to,int cap){ edge[size].to=to; edge[size].cap=cap; edge[size].next=head[from]; head[from]=size++;}void add(int a,int b,int c){ _add(a,b,c); _add(b,a,0);}bool bfs(int s,int t)//对层次网络进行编号{ queue<int> Q; memset(dis,-1,sizeof(dis));//将所有点的层次设为-1 dis[s]=0;//s入队 Q.push(s); while(!Q.empty()) { int v=Q.front();Q.pop();//取队首元素 if(v==t)return true; for(int i=head[v];i!=-1;i=edge[i].next)//找邻接点 { if(dis[edge[i].to]==-1&&edge[i].cap>0)//如果存在邻接点并且还未被编入层次网络 { dis[edge[i].to]=dis[v]+1; Q.push(edge[i].to); } } } return false;}int dfs(int x,int t,int maxc)//从节点x到汇点t的最大可增广流量,maxc表示当前可容许的最大容量{ if(x==t)return maxc; int ret,flow;ret=0; for(int i=head[x];i!=-1;i=edge[i].next) { if(edge[i].cap>0&&dis[edge[i].to]==dis[x]+1) { flow=dfs(edge[i].to,t,min(maxc-ret,edge[i].cap)); edge[i].cap-=flow; edge[i^1].cap+=flow; ret+=flow; if(ret==maxc)return ret; } } return ret;}int dinic(int s,int t){ int ans=0; while(bfs(s,t))//每次重建层次网络 ans+=dfs(s,t,inf);//如果找到一条增广路 return ans;}void make_set(){ for(int i=1;i<=m;i++) father[i]=i;}int find_set(int x){ if(x!=father[x]) father[x]=find_set(father[x]); return father[x];}void union_set(int x,int y){ int a=find_set(x); int b=find_set(y); if(a==b)return; father[a]=b;}bool is_connect(){ int cnt=-1; for(int i=1;i<=m;i++) if(father[i]==i)cnt++; if(cnt==0)return true; return false;}int main(){ freopen("in","r",stdin); int a,b,c; scanf("%d",&n); while(n--) { clear(); scanf("%d %d",&m,&s); make_set(); for(int i=0;i<s;i++) { scanf("%d %d %d",&a,&b,&c); union_set(a,b); outd[a]++;ind[b]++; if(c==0)//如果是无向的,变为单向的。 add(a,b,1); } if(!is_connect())puts("impossible"); else { int tot=0; bool flag=false; for(int i=1;i<=m;i++) { if(outd[i]>ind[i]) { int ans=outd[i]-ind[i]; if(ans&1){flag=true;break;} add(0,i,ans/2); tot+=ans/2; } else { int ans=ind[i]-outd[i]; if(ans&1){flag=true;break;} add(i,m+1,ans/2); } } if(flag)puts("impossible"); else { if(dinic(0,m+1)==tot)puts("possible");//检查是否满流 else puts("impossible"); } } } return 0;}
- POJ 1637 Sightseeing tour (混合图欧拉回路)
- poj 1637 Sightseeing tour(混合图欧拉回路)
- poj -- 1637 Sightseeing tour(混合图欧拉回路)
- [POJ 1637]Sightseeing tour[混合图欧拉回路]
- POJ 1637:Sightseeing tour 混合图欧拉回路
- 【POJ 1637】Sightseeing tour 混合图欧拉回路 最大流
- hdu 1956 || poj 1637 Sightseeing tour (混合图欧拉回路)
- POJ 1637 Sightseeing tour (混合图欧拉回路,网络最大流)
- POJ 1637 Sightseeing tour (混合图欧拉回路)
- 【最大流+混合图欧拉回路】POJ-1637 Sightseeing tour
- POJ 1637 Sightseeing tour 混合图欧拉回路 最大流
- poj 1637 Sightseeing tour 混迹图欧拉回路
- POJ 1637 Sightseeing tour (混合图的欧拉回路)
- poj 1637 Sightseeing tour(混合欧拉回路)
- poj 1637 Sightseeing tour(混合欧拉回路)
- POJ 1637 Sightseeing tour(混合欧拉回路,网络流)
- POJ 1637 Sightseeing tour 混合欧拉回路
- POJ 1637 Sightseeing tour(混合图的欧拉回路)
- hdu 1250 大树
- 杭电--2064--汉诺塔III--数学题
- H.264+RTP
- java中的xml解析以及转化为list
- 笔试面试算法
- POJ 1637 Sightseeing tour (混合图欧拉回路)
- iOS: NSObject的方法classFallbacksForKeyedArchiver
- 关于Preference的一点理解
- 杭电--2077--汉诺塔IV--数学题
- POJ1724--ROADS
- socket编程
- XML文件格式语法及DTD
- hdu1158 Employment Planning
- C语言几种常见排序算法(一)