BZOJ 2095 [Poi2010]Bridges 二分 最大流(混合图欧拉回路)
来源:互联网 发布:战争电影推荐 知乎 编辑:程序博客网 时间:2024/05/29 04:07
题目大意:给出一张n个点m条边的联通图,无重边,每条边有正反两个权值。现要从点1出发经过每条边每个点一次,问最大边权最小是多少。
最大最小容易想到二分,问题是如何判断是否有欧拉回路。
图不连通自然没有欧拉回路。
将大于限制的边设为不可走,新的图变成了混合图,即同时存在有向边和无向边。
首先,有向图的欧拉回路存在的条件是入度等于出度。
可以将无向边随意定向,默认从x到y。记一个点的度数为入度-出度。现在问题转化为如何转换无向边的方向使所有点的度数为0。若度数为奇数则一定没有欧拉回路因为将一条边反向会使一个点的度数加或减2,一定不可能得到0。
用网络流来判断。
对于每条无向边,y向x连边,流量为1,表示边可以反向。
对于每个点x,如果度数大于0,源点向x连边,否则x向汇点连边,流量为度数除以2,表示一个点的度数变成0需要的变化量。
如果满流则说明有欧拉回路
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define N 1005#define INF 1000000000using namespace std;struct Data { int a,b,c,d; void scan() { scanf("%d%d%d%d",&a,&b,&c,&d); if(c>d) swap(c,d), swap(a,b); }}g[N*2];struct Edge { int from,to,nxt,cap; Edge() {} Edge(int _from,int _to,int _nxt,int _cap): from(_from),to(_to),nxt(_nxt),cap(_cap) {}}e[N*10];int n,m,tot=-1,S,T,fir[N],d[N],pa[N],deg[N];int root(int x) { return pa[x]==x ? pa[x] : pa[x]=root(pa[x]); }void Add_Edge(int from,int to,int cap) { e[++tot]=Edge(from,to,fir[from],cap), fir[from]=tot; e[++tot]=Edge(to,from,fir[to],0), fir[to]=tot; return ;}bool bfs() { queue<int> q; for(int i=S;i<=T;++i) d[i]=-1; d[S]=0, q.push(S); while(!q.empty()) { int x=q.front(); q.pop(); for(int i=fir[x];~i;i=e[i].nxt) { if(!e[i].cap || d[e[i].to]!=-1) continue; d[e[i].to]=d[x]+1; if(e[i].to==T) return true; q.push(e[i].to); } } return false;}int dfs(int x,int now) { if(!now || x==T) return now; int f,flow=0; for(int i=fir[x];~i;i=e[i].nxt) { if(d[e[i].to]!=d[x]+1) continue; f=dfs(e[i].to,min(e[i].cap,now)); if(!f) continue; e[i].cap-=f, e[i^1].cap+=f; now-=f, flow+=f; if(!now) break; } if(!flow) d[x]=-1; return flow;}int Dinic() { int maxflow=0; while(bfs()) maxflow+=dfs(S,INF); return maxflow;}bool check(int lim) { fir[S]=fir[T]=-1; tot=-1; for(int i=1;i<=n;++i) pa[i]=i, deg[i]=0, fir[i]=-1; int cnt=n; for(int i=1;i<=m;++i) { if(g[i].d<=lim) { ++deg[g[i].a], --deg[g[i].b]; int pa_a=root(g[i].a),pa_b=root(g[i].b); if(pa_a!=pa_b) pa[pa_a]=pa_b, --cnt; Add_Edge(g[i].a,g[i].b,1); } else if(g[i].c<=lim) { --deg[g[i].a], ++deg[g[i].b]; int pa_a=root(g[i].a),pa_b=root(g[i].b); if(pa_a!=pa_b) pa[pa_a]=pa_b, --cnt; } } if(cnt>1) return false; for(int i=1;i<=n;++i) { if(deg[i]&1) return false; if(deg[i]>0) Add_Edge(S,i,deg[i]>>1); else Add_Edge(i,T,-deg[i]>>1); } Dinic(); for(int i=fir[S];~i;i=e[i].nxt) if(e[i].cap) return false; return true;}int main() { scanf("%d%d",&n,&m); T=n+1; for(int i=1;i<=m;++i) g[i].scan(); int l=1,r=1001,mid,ans=-1; while(l<=r) { mid=l+r>>1; if(check(mid)) ans=mid, r=mid-1; else l=mid+1; } if(ans==-1) puts("NIE"); else printf("%d\n",ans); return 0;}
阅读全文
0 0
- BZOJ 2095 [Poi2010]Bridges 二分 最大流(混合图欧拉回路)
- 2095: [Poi2010]Bridges 二分+混合图欧拉回路(网络流)
- BZOJ 2095 [Poi2010]Bridges 二分+最大流
- bzoj 2095: [Poi2010]Bridges (二分+最大流+欧拉图)
- [BZOJ2095]-[Poi2010]Bridges-二分答案+混合图欧拉回路判定
- Bzoj2095:[Poi2010]Bridges:混合图欧拉回路,网络流
- BZOJ 2095 Poi2010 Bridges 二分答案+网络流
- bzoj 2095: [Poi2010]Bridges 二分答案+网络流
- bzoj2095: [Poi2010]Bridges 二分+最大流
- BZOJ 2095: [Poi2010]Bridges
- BZOJ 2095 Bridges (二分 混合图的欧拉回路)
- [BZOJ2095][Poi2010]Bridges(二分+最大流+欧拉图)
- [BZOJ]2095 二分答案 + 混合图欧拉回路判定
- 【BZOJ2095】【最大流】[Poi2010]Bridges 题解
- 图论欧拉回路初步 & BZOJ2095 POI2010 Bridges
- 2095: [Poi2010]Bridges
- POJ1637-最大流判断混合图欧拉回路
- poj 1637 混合图欧拉回路,最大流
- Retrofit图片上传及进度的显示
- android各版本名字及对应API
- 团队协作技术
- mysql设置datetime默认值为now(但不支持)
- Docker安装流程
- BZOJ 2095 [Poi2010]Bridges 二分 最大流(混合图欧拉回路)
- Calendar类获取当前时间方法
- 怎样解决头文件中找不到QGLWidget
- Maven学习 (五) Elipse中发布一个Maven项目到Tomcat
- POI(excel)
- 国内最全最详细的Hadoop2.2.0集群的HA高可靠的最简单配置
- java两个int相除,返回保留两位小数
- iOS SRWebSocket原理分析及API使用
- arcgis js api单独加载动态地图服务问题