【BZOJ2095】【POI2010】Bridge 网络流
题目大意
给你一个无向图,每条边的两个方向的边权可能不同。要求找出一条欧拉回路使得路径上的边权的最大值最小。无解输出"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;
else
l=mid+1;
}
if(l>1000)
printf("NIE\n");
else
printf("%d\n",l);
return 0;
}
【BZOJ2095】【POI2010】Bridge 网络流的更多相关文章
- BZOJ2095 POI2010 Bridges 【二分+混合图欧拉回路】
BZOJ2095 POI2010 Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛 ...
- [BZOJ2095][Poi2010]Bridges 二分+网络流
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1187 Solved: 408[Submit][Sta ...
- 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 604 Solved: 218[Submit][Stat ...
- BZOJ2095 [Poi2010]Bridges
首先二分答案...然后这张图变成了有一些有向边,有一些无向边 然后就是混合图欧拉回路的判断 我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度 对于混合图...先不管有向边,把无向边 ...
- 【BZOJ2095】 Bridge
Time Limit: 1000 ms Memory Limit: 128 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个 ...
- BZOJ2095:[POI2010]Bridges(最大流,欧拉图)
Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1 ...
- bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)
传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路 ...
- [BZOJ2095][Poi2010]Bridges 最大流(混合图欧拉回路)
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海, ...
- bzoj千题计划228:bzoj2095: [Poi2010]Bridges
http://www.lydsy.com/JudgeOnline/problem.php?id=2095 二分答案,判断是否存在混合图的欧拉回路 如果只有一个方向的风力<=mid,这条边就是单向 ...
随机推荐
- vue 二三倍图适配,1像素边框
//文件名为mixin.scss// 2,3倍图适配 @mixin bg-image($url){ background-image: url("~imgs/icon/" + $u ...
- stark组件之展示数据(查)
1.编辑按钮构建完成 2.构造表头,删除,checkbox,links编辑 3.代码+总结 1.编辑按钮构建完成 1.必备知识预习 第一个会打印5. 第二个输出alex alex是person ...
- PHP的优化建议(仅借鉴)
转载: https://www.awaimai.com/1050.html 1 字符串 1.1 少用正则表达式 能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率高于正则 ...
- laravel门面和服务提供者使用
关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...
- spark单击 搭建
http://files.cnblogs.com/files/yxnyd/spark.zip
- opencv自带fast_math.hpp
cvRound cvFloor cvCeil cvIsNaN cvIsInf
- hdu1421_搬寝室
题目:搬寝室 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1421 #include<stdio.h> #include<algor ...
- unsupported time zone specified undefined
unsupported time zone specified undefined 出现了这个问题,莫名其妙的,上次被我下回去了,真的是下回去的,我一去查看,坐在电脑前面问题就不见了…… 具体出现 ...
- Java多线程之synchronized线程锁
package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/18 * @Descrip ...
- zh-CN、zh-Hans区别
zh-CN:地区限制匹配规范,表示用在中国大陆区域的中文.包括各种大方言.小方言.繁体.简体等等都可以被匹配到. zh-Hans:语言限制匹配规范,表示简体中文.适用区域范围是全宇宙用中文简体的地方, ...