题面

nnn个点,mmm条双向边(正向与反向权值不同),求经过最大边权最小的欧拉回路的权值

分析

commonc大佬博客

  • 精髓就是通过最大流调整无向边的方向使得所有点的入度等于出度

CODE

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template<typename T>inline void read(T &num) {
char ch; while((ch=getchar())<'0'||ch>'9');
for(num=0;ch>='0'&&ch<='9';num=num*10+ch-'0',ch=getchar());
}
const int inf = 1e9;
const int MAXN = 1005;
const int MAXM = 100005;
int n, m, p, fir[MAXN], S, T, tot, cnt, deg[MAXN];
struct edge { int to, nxt, c; }e[MAXM];
inline void add(int u, int v, int cc) {
e[cnt] = (edge){ v, fir[u], cc }; fir[u] = cnt++;
e[cnt] = (edge){ u, fir[v], 0 }; fir[v] = cnt++;
}
int dis[MAXN], vis[MAXN], info[MAXN], cur, q[MAXN];
inline bool bfs() {
int head = 0, tail = 0;
vis[S] = ++cur; q[tail++] = S;
while(head < tail) {
int u = q[head++];
for(int i = fir[u]; ~i; i = e[i].nxt)
if(e[i].c && vis[e[i].to] != cur)
vis[e[i].to] = cur, dis[e[i].to] = dis[u] + 1, q[tail++] = e[i].to;
}
if(vis[T] == cur) memcpy(info, fir, (T+1)<<2);
return vis[T] == cur;
}
int dfs(int u, int Max) {
if(u == T || !Max) return Max;
int flow=0, delta;
for(int &i = info[u]; ~i; i = e[i].nxt)
if(e[i].c && dis[e[i].to] == dis[u] + 1 && (delta=dfs(e[i].to, min(e[i].c, Max-flow)))) {
e[i].c -= delta, e[i^1].c += delta, flow += delta;
if(flow == Max) return flow;
}
return flow;
}
inline int dinic() {
int flow=0, x;
while(bfs()) {
while((x=dfs(S, inf))) flow+=x;
}
return flow;
}
int A[2005], B[2005], C[2005], D[2005];
inline bool check(int mid) {
memset(fir, -1, sizeof fir); cnt = 0;
for(int i = 1; i <= m; ++i) {
if(C[i] > mid) return 0;
if(D[i] <= mid)
add(A[i], B[i], 1);
}
int sum = 0;
for(int i = 1; i <= n; ++i)
if(deg[i] > 0) add(i, T, deg[i]/2);
else if(deg[i] < 0) add(S, i, -deg[i]/2), sum -= deg[i]/2;
return dinic() == sum;
}
int main () {
read(n), read(m); S = 0; T = n+1;
for(int i = 1; i <= m; ++i) {
read(A[i]), read(B[i]), read(C[i]), read(D[i]);
if(C[i] > D[i]) swap(A[i], B[i]), swap(C[i], D[i]);
--deg[A[i]], ++deg[B[i]];
}
for(int i = 1; i <= n; ++i)
if(deg[i] % 2) return printf("NIE"), 0;
int l = 1, r = 1000, mid;
while(l < r) {
mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid+1;
}
printf("%d\n", l);
}

BZOJ 2095 [Poi2010]Bridges (二分+最大流判断混合图的欧拉回路)的更多相关文章

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

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

  2. BZOJ 2095: [Poi2010]Bridges

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

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

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

  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(二分法+混合图的欧拉回路)

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

  6. poj--1637--Sightseeing tour(网络流,最大流判断混合图是否存在欧拉图)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Sub ...

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

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

  8. BZOJ 2095 [POI2010]Bridges (最大流、欧拉回路)

    洛谷上有这题,但是输出方案缺SPJ..(而且我也懒得输出方案了) 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2095 题解: 首先判 ...

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

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

随机推荐

  1. windows MinGW gcc 编译乱码问题

    问题描述 一般很多编辑器默认都是保存成utf-8文件,然而在输出中文的时候出现了乱码?另外试了其他方法,有的乱码,有的不乱? MinGW gcc 编译 utf-8 文件的时候乱码 MinGW gcc ...

  2. python多任务基础

    1.多任务:两个程序段同时运行2.为某个函数创建线程并启动: import threading 线程名 = threading.Thread(target = 函数名,args = 参数元组) #创建 ...

  3. 项目element-ui checkbox里面获取选中项 实现批量删除 修改

    <el-table :data="tableData" stripe border style="width: 100%" @selection-chan ...

  4. 将物理机系统转为虚拟机系统 p2v

    ref : https://blog.csdn.net/gsls200808/article/details/77932713 背景: 在公司有台机子主要负责某产品的升级与维护,出于各种原因,该产品需 ...

  5. 如何将Linux的工程原封不动地移植到Windows上面

    习惯在Linux下进行开发.但是由于工作需要,不得不与其他使用Windows的项目组同事对接,同事要求我给出可用的程序,而我只有基于makefile的传统工程. 改动到VS工程上发现一部分头文件在Wi ...

  6. java——多态例题

    class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { re ...

  7. java运算符那些事

    && 逻辑与 &&先运算&&左边的算式,如果为假,则直接停止,后面不管有多少运算式都不再运算,如果为真则继续判断后面的式子,只有所有的条件全部成立,才会 ...

  8. mysql5.7主主(双主)复制

    在server1上操作 vi /etc/my.cnf 修改或添加下面这几行: server-id=1 log-bin=mysql-bin # 启用二进制日志 auto-increment-increm ...

  9. Mysql高可用集群环境介绍

    MySQL高可用集群环境搭建 01.MySQL高可用环境方案 02.MySQL主从复制原理 03.MySQL主从复制作用 04.在Linux环境上安装MySQL 05.在MySQL集群环境上配置主从复 ...

  10. 【Transact-SQL】计算整个表中所有值的出现的次数

    原文:[Transact-SQL]计算整个表中所有值的出现的次数 一个表有3列,5行,那么一共有15个值,现在要计算整个表中所有值在表中出现的次数,不过这里表的列数是不确定的,上面的例子是3列,实际上 ...