题目大意

​  给你一个无向图,每条边的两个方向的边权可能不同。要求找出一条欧拉回路使得路径上的边权的最大值最小。无解输出"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 网络流的更多相关文章

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

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

  2. [BZOJ2095][Poi2010]Bridges 二分+网络流

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1187  Solved: 408[Submit][Sta ...

  3. 【BZOJ-2095】Bridge 最大流 + 混合图欧拉回路 + 二分

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 218[Submit][Stat ...

  4. BZOJ2095 [Poi2010]Bridges

    首先二分答案...然后这张图变成了有一些有向边,有一些无向边 然后就是混合图欧拉回路的判断 我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度 对于混合图...先不管有向边,把无向边 ...

  5. 【BZOJ2095】 Bridge

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

  6. BZOJ2095:[POI2010]Bridges(最大流,欧拉图)

    Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1 ...

  7. bzoj2095: [Poi2010]Bridges(二分+混合图求欧拉回路)

    传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路 ...

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

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

  9. bzoj千题计划228:bzoj2095: [Poi2010]Bridges

    http://www.lydsy.com/JudgeOnline/problem.php?id=2095 二分答案,判断是否存在混合图的欧拉回路 如果只有一个方向的风力<=mid,这条边就是单向 ...

随机推荐

  1. vue 二三倍图适配,1像素边框

    //文件名为mixin.scss// 2,3倍图适配 @mixin bg-image($url){ background-image: url("~imgs/icon/" + $u ...

  2. stark组件之展示数据(查)

      1.编辑按钮构建完成 2.构造表头,删除,checkbox,links编辑 3.代码+总结   1.编辑按钮构建完成 1.必备知识预习 第一个会打印5. 第二个输出alex alex是person ...

  3. PHP的优化建议(仅借鉴)

    转载: https://www.awaimai.com/1050.html 1 字符串 1.1 少用正则表达式 能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率高于正则 ...

  4. laravel门面和服务提供者使用

      关于laravel门面和服务提供者使用的一点见解,门面之词,不足之处,还请多多指教. 在laravel中,我们可能需要用到自己添加的类时,可以建立一个文件夹专门存放类文件,也可以使用laravel ...

  5. spark单击 搭建

    http://files.cnblogs.com/files/yxnyd/spark.zip

  6. opencv自带fast_math.hpp

    cvRound cvFloor cvCeil cvIsNaN cvIsInf

  7. hdu1421_搬寝室

    题目:搬寝室 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1421 #include<stdio.h> #include<algor ...

  8. unsupported time zone specified undefined

    unsupported time zone specified undefined   出现了这个问题,莫名其妙的,上次被我下回去了,真的是下回去的,我一去查看,坐在电脑前面问题就不见了…… 具体出现 ...

  9. Java多线程之synchronized线程锁

    package org.study2.javabase.ThreadsDemo.sync; /** * @Auther:GongXingRui * @Date:2018/9/18 * @Descrip ...

  10. zh-CN、zh-Hans区别

    zh-CN:地区限制匹配规范,表示用在中国大陆区域的中文.包括各种大方言.小方言.繁体.简体等等都可以被匹配到. zh-Hans:语言限制匹配规范,表示简体中文.适用区域范围是全宇宙用中文简体的地方, ...