洛谷上有这题,但是输出方案缺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. Hadoop MapReduce 运行步骤

    步骤:[使用java编译程序,生成.class文件] [将.class文件打包为jar包] [运行jar包(需要启动Hadoop)] [查看结果] 具体实现:1.添加程序所需要的依赖vim ~/.ba ...

  2. nginx - ubutun下安装nginx(详述编译方法)

    一.使用apt命令安装 sudo apt-get install nginx 二.编译方法安装(个人实践方法,具体见官方文档) 1)说明:我使用的虚拟机是64位 ubuntu server14.04, ...

  3. P3297 [SDOI2013]逃考

    传送门 完全看不出这思路是怎么来的-- 首先对于两个亲戚,他们监视范围的边界是他们连线的中垂线.那么对于一个亲戚来说它能监视的范围就是所有的中垂线形成的半平面交 然后如果某两个亲戚的监视范围有公共边, ...

  4. Hexo 添加Live2D看板娘

    title: Hexo 添加 Live2D看板娘 二次元什么的最喜欢了[大好きです] 准备 项目地址 live2d模型 部分模型预览 开始 首先进入Hexo博客根目录安装live2d插件 $ npm ...

  5. 06使用NanoPiM1Plus在Android4.4.2下接U盘

    06使用NanoPiM1Plus在Android4.4.2下接U盘 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 21504965 AT qq.com 完成时间:2017/12/5 17:51 版本:V ...

  6. PAT甲级考前整理(2019年3月备考)之一

       转载请注明出处:https://www.cnblogs.com/jlyg/p/7525244.html 终于在考前,刷完PAT甲级131道题目,不容易!!!每天沉迷在刷题之中而不能超脱,也是一种 ...

  7. codeforces_305C_STLset

    C. Ivan and Powers of Two time limit per test 0.5 seconds memory limit per test 256 megabytes input ...

  8. 如何安装Ant,配置环境变量??

    Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发. Ant是一个基于Java,并且主要用于Java工程的构建工具.Ant本意是A ...

  9. CAD与用户互在图面上得到一个矩形框(com接口VB语言)

    主要用到函数说明: MxDrawXCustomFunction::ExApp_CutDwg 与用户互在图面上得到一个矩形框,详细说明如下: 参数 说明 IN DOUBLE dX1 保存范围的左下角位置 ...

  10. 顶点的度 (20 分) Java解法

    顶点的度 顶点的图.给定一个有向图,输出各顶点的出度和入度. 输入格式: 输入文件中包含多个测试数据,每个测试数据描述了一个无权有向图.每个测试数据的第一行为两个正整数n 和m,1 ≤ n ≤ 100 ...