洛谷上有这题,但是输出方案缺SPJ。。(而且我也懒得输出方案了)

题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2095

题解: 首先判掉度数有奇数的特殊情况,一眼能看出来二分答案(二分下界要设成每条边较小权值的最大值),然后转化成:

给定一张图,有些边有方向,有些边无方向,问是否能给无向边定向使得所有边形成欧拉回路。

看着这个完全没觉得这像网络流啊……

好吧只要想到用网络流来做就非常简单了

考虑欧拉回路不就是每个点入度等于出度?现在入度不等于出度对吧?那我们考虑“入度等于出度”这个条件像什么?像流量平衡对吧。在网络流中每个点流入的流量等于流出的流量。

那么我们的目标是对于每个点都要求其入度出度相等均为\(\frac{du[i]}{2}\) (\(du[i]\)为\(i\)的度数,\(dui[i],duo[i]\)分别为入度出度)

现在我们已有的有向边入度比出度多\(dui[i]-duo[i]\), 那么它在无向边定向之后就要出度比入度多\(dui[i]-duo[i]\).

所以如果不加任何改动拿无向边跑最大流是出度等于入度,那么从\(S\)连一条\(dui[i]-duo[i]\)的边跑最大流就相当于出度比入度多\(dui[i]-duo[i]\)了。同理,如果出度比入度多,这条边就要连向T,权值为差的绝对值。

判断是否满流即可。

时间复杂度\(O(MaxFlow(n,m)\times \log W)\) (\(W\)为权值)

UPD: 为啥网上题解和我都不一样??我的做法是错的吗??求教

网上的题解都是: 对于无向边先随便定个向,然后加这条边的反向边边权为\(1\),对于每个点与\(S\)或者\(T\)连的边权是出入度之差除以\(2\), 因为每反向一条边相当于入度\(+1\)出度\(-1\), 对差的影响是\(2\).

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int N = 1002;
const int M = 8000;
const int INF = 1e7; namespace MaxFlow
{
struct Edge
{
int v,w,nxt,rev;
} e[(M<<1)+3];
int n,en,s,t;
int dep[N+3];
int que[N+3];
int fe[N+3];
int te[N+3];
void clear()
{
for(int i=1; i<=n; i++) fe[i] = te[i] = 0;
for(int i=1; i<=en; i++) e[i].v = e[i].w = e[i].nxt = e[i].rev = 0;
n = en = s = t = 0;
}
void addedge(int u,int v,int w)
{
en++; e[en].v = v; e[en].w = w;
e[en].nxt = fe[u]; fe[u] = en; e[en].rev = en+1;
en++; e[en].v = u; e[en].w = 0;
e[en].nxt = fe[v]; fe[v] = en; e[en].rev = en-1;
}
bool bfs()
{
for(int i=1; i<=n; i++) dep[i] = 0;
int head = 1,tail = 1; que[tail] = s; dep[s] = 1;
while(head<=tail)
{
int u = que[head]; head++;
for(int i=fe[u]; i; i=e[i].nxt)
{
if(dep[e[i].v]==0 && e[i].w>0)
{
dep[e[i].v] = dep[u]+1;
tail++; que[tail] = e[i].v;
}
}
}
return dep[t]!=0;
}
int dfs(int u,int cur)
{
if(u==t) {return cur;}
int rst = cur;
for(int i=te[u]; i; i=e[i].nxt)
{
if(dep[e[i].v]==dep[u]+1 && e[i].w>0 && rst>0)
{
int flow = dfs(e[i].v,min(rst,e[i].w));
if(flow>0)
{
rst -= flow; e[i].w -= flow; e[e[i].rev].w += flow;
if(e[i].w>0) te[u] = i;
if(rst==0) {return cur;}
}
}
}
return cur-rst;
}
int dinic(int _n,int _s,int _t)
{
n = _n,s = _s,t = _t;
int ret = 0;
while(bfs())
{
for(int i=1; i<=n; i++) te[i] = fe[i];
ret += dfs(s,INF);
}
return ret;
}
}
using MaxFlow::addedge;
using MaxFlow::dinic; struct AEdge
{
int u,v,w1,w2;
} ae[M+3];
int dui[N+3],duo[N+3],du[N+3];
int n,m; void clear()
{
for(int i=1; i<=n; i++) dui[i] = duo[i] = 0;
MaxFlow::clear();
} int main()
{
scanf("%d%d",&n,&m); int left = 0,right = 0;
for(int i=1; i<=m; i++)
{
scanf("%d%d%d%d",&ae[i].u,&ae[i].v,&ae[i].w1,&ae[i].w2);
left = max(left,min(ae[i].w1,ae[i].w2));
right = max(right,max(ae[i].w1,ae[i].w2));
du[ae[i].u]++; du[ae[i].v]++;
}
for(int i=1; i<=n; i++)
{
if(du[i]&1) {printf("NIE"); return 0;}
}
while(left<right)
{
int mid = left+((right-left)>>1);
int std = 0;
for(int i=1; i<=m; i++)
{
if(ae[i].w1<=mid && ae[i].w2<=mid)
{
addedge(ae[i].u+2,ae[i].v+2,1);
addedge(ae[i].v+2,ae[i].u+2,1);
}
else if(ae[i].w1<=mid)
{
duo[ae[i].u]++; dui[ae[i].v]++;
}
else if(ae[i].w2<=mid)
{
duo[ae[i].v]++; dui[ae[i].u]++;
}
}
for(int i=1; i<=n; i++)
{
if(dui[i]>duo[i])
{
addedge(i+2,2,dui[i]-duo[i]);
std += dui[i]-duo[i];
}
else if(duo[i]>dui[i])
{
addedge(1,i+2,duo[i]-dui[i]);
}
}
int ans = dinic(n+2,1,2);
if(ans==std) {right = mid;}
else {left = mid+1;}
clear();
}
printf("%d\n",right);
return 0;
}

BZOJ 2095 [POI2010]Bridges (最大流、欧拉回路)的更多相关文章

  1. bzoj 2095: [Poi2010]Bridges [混合图欧拉回路]

    2095: [Poi2010]Bridges 二分答案,混合图欧拉路判定 一开始想了一个上下界网络流模型,然后发现不用上下界网络流也可以 对于无向边,强制从\(u \rightarrow v\),计算 ...

  2. BZOJ.2095.[POI2010]Bridges(最大流ISAP 二分 欧拉回路)

    题目链接 最小化最大的一条边,二分答案.然后就变成了给一张无向图定向使其为欧拉回路 二分答案后对于一个位置的两条边可能都保留,即双向边,需要给它定向:可能只保留小的一条,即单向边,不需考虑 如何给它定 ...

  3. BZOJ 2095: [Poi2010]Bridges

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

  4. bzoj 2095 [Poi2010]Bridges 判断欧拉维护,最大流+二分

    [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1448  Solved: 510[Submit][Status][D ...

  5. BZOJ 2095 [Poi2010]Bridges (二分+最大流判断混合图的欧拉回路)

    题面 nnn个点,mmm条双向边(正向与反向权值不同),求经过最大边权最小的欧拉回路的权值 分析 见 commonc大佬博客 精髓就是通过最大流调整无向边的方向使得所有点的入度等于出度 CODE #i ...

  6. bzoj 2095: [Poi2010]Bridges(二分法+混合图的欧拉回路)

    [题意] 给定n点m边的无向图,对于边u,v,从u到v边权为c,从v到u的边权为d,问能够经过每条边一次且仅一次,且最大权值最小的欧拉回路. [思路] 二分答案mid,然后切断权值大于mid的边,原图 ...

  7. 【刷题】BZOJ 2095 [Poi2010]Bridges

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

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

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

  9. [Poi2010]Bridges 最大流+二分答案 判定混合图欧拉回路

    https://darkbzoj.cf/problem/2095 bzoj 相同的题挂了,这个oj可以写. 题目就是要我们找一条欧拉回路(每个桥经过一次就好,不管方向),使得这条回路上权值最大的尽量小 ...

随机推荐

  1. P1266 速度限制(分层图spfa)

    P1266 速度限制 题目描述 在这个繁忙的社会中,我们往往不再去选择最短的道路,而是选择最快的路线.开车时每条道路的限速成为最关键的问题.不幸的是,有一些限速的标志丢失了,因此你无法得知应该开多快. ...

  2. js 上传头像

    css .con4{width: 230px;height: auto;overflow: hidden;margin: 20px auto;color: #FFFFFF;} .con4 .btn{w ...

  3. 微信小程序获取自定义属性值

    写小程序的时候用到了自定义属性,特地来记录一下 特别是这个坑,必须得说一说 wxml <view class='box' bindtap='getValue'> <view clas ...

  4. sql server 大数据处理

    对SQL Server数据表进行分区的过程分为三个步骤: 1)建立分区函数 2)建立分区方案 3)对表格进行分区 第一个步骤:建立分区函数 分区函数定义[u]how[/u],即你想要SQL Serve ...

  5. 二分搜索 POJ 1064 Cable master

    题目传送门 /* 题意:n条绳子问切割k条长度相等的最长长度 二分搜索:搜索长度,判断能否有k条长度相等的绳子 */ #include <cstdio> #include <algo ...

  6. 初识mybatis之入门案例

    我也是自学了一下,在idea中基于maven的mybatis的配置.有什么不对的地方,请指正,谢谢. 1.1咋们先来配置测试一下,配置mybatis的图解: 1.2 pom.xml需要mybatis的 ...

  7. Sublime——基本操作

    基本安装 程序下载地址:https://www.sublimetext.com/ package control安装 View -> Show Console打开控制台或者用快捷键ctrl+~打 ...

  8. Java 基础入门随笔(9) JavaSE版——文档注释

    上节中写了一些static变量以及静态的方法的定义使用以及与非静态的差别,这节补充下: 如果在一个类中所有方法都为静态的,且无成员变量,这时候需要对对应的类进行限制该类无法创建对象,具体操作如下: p ...

  9. Flask框架 之第一个Flask程序

    from flask import Flask # 创建flask应用对象 # __name__ 代表当前模块名称 # flask以当前目录为总目录,static目录为静态目录,templates为模 ...

  10. arx 插入图片

    #include <ShLwApi.h> #pragma comment(lib, "ShLwApi.lib") //插入影像图 Acad::ErrorStatus i ...