题目大意

​  给你一个无向图,每条边的两个方向的边权可能不同。要求找出一条欧拉回路使得路径上的边权的最大值最小。无解输出"NIE"。
  \(2\leq n\leq 1000,1\leq m\leq 2000\)

题解

​  我们先二分答案\(ans\),把边权大于\(ans\)的边删掉。

​  现在图中还剩下一些有向边和一些无向边,也就是说这是一个混合图。

​  混合图的欧拉回路怎么求?

​  先把无向边定向(方向任意),求出每个点的出度\(d1_i\)和入度\(d2_i\)。如果存在点\(i\)使得\(|d1_i-d2_i|\)为奇数,则无解。因为你怎么反向都不可能把\(d1_i-d2_i\)变成\(0\)。

​  然后把无向边按定向的反方向在图中连边,容量为\(1\)。对于一个点\(i\),如果\(d1_i>d2_i\),则连边\(i\text{->}T\),容量为\(\frac{d1_i-d2_i}{2}\),否则连边\(S\text{->}i\),容量为\(\frac{d2_i-d1_i}{2}\)。

​  最后跑一次最大流。如果满流就有解,否则无解。

  还要用并查集判一下是不是连通图。

​  为什么这是对的?每流过一条边就表示把这条边反向。对这个网络求最大流就是调整尽可能多的边。流量平衡就表示一个点的入度和出度相同。

​  这个图把边定向得到

​  

​  建图后跑最大流可以得到

  

​  把满流边反向后得到

  

​  这就是一个欧拉回路了

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
struct list
{int v[100010];int w[100010];int t[100010];int h[1010];int n;void clear(){memset(h,0,sizeof h);n=0;}void add(int x,int y,int z){n++;v[n]=y;w[n]=z;t[n]=h[x];h[x]=n;}
};
list l;
void add(int x,int y,int z)
{l.add(x,y,z);l.add(y,x,0);
}
int d[1010];
int S,T;
int bfs()
{memset(d,-1,sizeof d);queue<int> q;q.push(S);d[S]=0;int x,i;while(!q.empty()){x=q.front();q.pop();for(i=l.h[x];i;i=l.t[i])if(l.w[i]&&d[l.v[i]]==-1){d[l.v[i]]=d[x]+1;if(l.v[i]==T)return 1;q.push(l.v[i]);}}return 0;
}
int op(int x)
{return ((x-1)^1)+1;
}
int dfs(int x,int flow)
{if(x==T)return flow;int c,s=0,i;for(i=l.h[x];i;i=l.t[i])if(l.w[i]&&d[l.v[i]]==d[x]+1){c=dfs(l.v[i],min(flow,l.w[i]));s+=c;flow-=c;l.w[i]-=c;l.w[op(i)]+=c;if(!flow)break;}return s;
}
int f[1010];
int find(int x)
{return f[x]==x?x:f[x]=find(f[x]);
}
int lx[2010],ly[2010],w1[2010],w2[2010];
int d1[2010],d2[2010];
int c[2010];//方向
int n,m;
int abs(int x)
{return x>0?x:-x;
}
int check(int p)
{memset(d1,0,sizeof d1);memset(d2,0,sizeof d2);int i;for(i=1;i<=n;i++)f[i]=i;for(i=1;i<=m;i++){if(p<w1[i]&&p<w2[i])return 0;if(p>=w1[i]){c[i]=0;d1[lx[i]]++;d2[ly[i]]++;f[find(lx[i])]=find(ly[i]);}else{c[i]=1;d1[ly[i]]++;d2[lx[i]]++;f[find(lx[i])]=find(ly[i]);}}for(i=1;i<=n;i++){if(abs(d1[i]-d2[i])&1)return 0;if(i>1&&find(i)!=find(i-1))return 0;}l.clear();S=n+1;T=n+2;for(i=1;i<=m;i++)if(p>=w1[i]&&p>=w2[i])add(ly[i],lx[i],1);
//      else
//          add(lx[i],ly[i],1);int s=0,ans=0;for(i=1;i<=n;i++)if(d1[i]>d2[i]){add(i,T,(d1[i]-d2[i])/2);s+=(d1[i]-d2[i])/2;}else if(d1[i]<d2[i])add(S,i,(d2[i]-d1[i])/2);while(bfs())ans+=dfs(S,0x7fffffff);return ans==s;
}
int main()
{
//  freopen("bzoj2095.in","r",stdin);scanf("%d%d",&n,&m);int i;for(i=1;i<=m;i++)scanf("%d%d%d%d",&lx[i],&ly[i],&w1[i],&w2[i]);int l=1,r=1001;int mid;while(l<r){mid=(l+r)>>1;if(check(mid))r=mid;elsel=mid+1;}if(l>1000)printf("NIE\n");elseprintf("%d\n",l);return 0;
}

转载于:https://www.cnblogs.com/ywwyww/p/8510609.html

【BZOJ2095】【POI2010】Bridge 网络流相关推荐

  1. BZOJ2095[Poi2010] Bridges

    BZOJ2095[Poi2010] Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小 ...

  2. BZOJ2095 POI2010 Bridges 【二分+混合图欧拉回路】

    BZOJ2095 POI2010 Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛 ...

  3. Bzoj2095:[Poi2010]Bridges:混合图欧拉回路,网络流

    题目链接:2095:[Poi2010]Bridges 二分答案建图后显然是混合图的欧拉回路,有向边删掉无向边随机定向计算入度-出度的差du[i],如果du[i]<0连边(i,T,-du[i]/2 ...

  4. bzoj2095 [Poi2010]Bridges

    bzoj [Poi2010]Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到 ...

  5. 图论欧拉回路初步 BZOJ2095 POI2010 Bridges

    反正对于现在的我来说是好题.顺便膜po大犇和dingchao大犇. 网络流什么的还是再开一个专题好了. 欧拉回路问题参考论文<欧拉回路性质与应用探究>by 仇荣琦. POI2010 题解整 ...

  6. 【BZOJ2095】 Bridge

    Time Limit: 1000 ms   Memory Limit: 128 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个 ...

  7. [BZOJ2095][Poi2010]Bridges 最大流(混合图欧拉回路)

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海, ...

  8. bzoj2095: [Poi2010]Bridges 二分+最大流

    想当年第一次看到这个题是在**p的一套模拟题里?然后当时想过二分也想过最大流.然后就是没有想到一块,最后知道做法后就不了了之了. #include <iostream> #include ...

  9. P3511 [POI2010]MOS-Bridges(网络流/欧拉回路)

    P3511 [POI2010]MOS-Bridges 给出一个图,边正着走和反着走的边权不同,求解最大边权最小的欧拉回路,输出方案. 首先看到最大边权最小我们就可以想到二分答案,然后现在在剩余的图上我 ...

最新文章

  1. EOS入门指南PART6——别忙着开发,先来看看智能合约数据是怎么存的
  2. 接口性能测试实战小结
  3. iOS之深入解析alloc、init与new的底层原理
  4. 6张信用卡欠款10000到47000不等,会被起诉坐牢吗?
  5. C++ stringstream介绍,使用方法与例子
  6. 骆驼祥子大事件时间轴_骆驼中的事件处理
  7. JEECG 商业版本最近新增什么功能啦?
  8. SilverLight中的数据绑定
  9. 奇怪的比赛--蓝桥杯
  10. restful可以转发么_RESTful 的收益是什么?
  11. 【渝粤教育】国家开放大学2018年秋季 0299-22T中国古代文学(1) 参考试题
  12. FastStone Capture 7.7 截图工具下载地址及使用
  13. OCP 创建可插拔数据库PDB
  14. 暴力破解zip,rar密码
  15. 如何查看微信小程序服务器域名并且修改
  16. 第6节 远程管理路由器及交换机—基于Cisco Packet Tracer
  17. java用户注册信息校验
  18. wireshark学习笔记
  19. 道家修真分哪几个境界?
  20. “气球” 的最大数量

热门文章

  1. linux内核计算list的长度,Linux内核通用链表 linux/list.h阅读
  2. php 判断ajax访问,PHP里判断是否Ajax请求
  3. tcs标准编写软件_【公益培训】知你所需 | 标准编写格式及TCS模板应用线上公益培训...
  4. Spring —— 容器内部逻辑
  5. jvm gc垃圾回收机制和参数说明amp;amp;Java JVM 垃圾回收(GC 在什么时候,对什么东西,做了什么事情)
  6. opencore0.6.3_Ubuntu 18.04 源码编译安装 PHP 7.3
  7. 西浦与杭电计算机选哪个,四邮四电究竟谁强谁弱?哪三所大学报考更有性价比?...
  8. semantic ui中文文档_Vuetify-广受欢迎的Material风格的开源UI框架
  9. 如何安装tensorflowGPU环境搭建(不报AVX2的警告)
  10. HTML+CSS+JS实现 ❤️canvas圆形水波进度条动画特效❤️