传送门

Luogu团队题链接

解题思路

首先二分答案,然后在所有边权小于二分值的边和所有点组成的图中判欧拉回路。

由于可能出现混合图,所以要用到网络流。

把所有无向边钦定一个方向,那么原图就是一个有向图。

那么存在欧拉回路的充要条件就所有点的入度等于出度且图联通。

我们考虑把点 \(x\) 的入度与出度之差记作 \(\Delta x\)。

那么对于所有的定向后的无向边 \((u,v)\),连一条从 \(u\rightarrow v\) 的容量为 \(1\) 的边。

表示将该条边反向可以使 \(\Delta u += 2,\Delta v -= 2\)。

然后考虑对于所有度数差小于 \(0\) 的点 \(x\),连一条 \(s \rightarrow x\) 的容量为 \(\frac{|\Delta x|}{2}\) 的边。

表示 \(x\) 需要操作这么多次,使得 \(\Delta x\) 达到 \(0\)。小于零的情况同理。

最后判断是否满流即可。

细节注意事项

  • 细节有点多,要有耐心

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <queue>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
} const int _ = 1010;
const int __ = 5010 * 2 + 1010 * 2;
const int INF = 2147483647; int tot = 1, head[_], nxt[__], ver[__], cap[__];
inline void Add_edge(int u, int v, int d)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, cap[tot] = d; }
inline void link(int u, int v, int d) { Add_edge(u, v, d), Add_edge(v, u, 0); } int n, m, s, t, liu, dgr[_], dep[_];
struct node{ int a, b, c, d; }g[__]; inline int bfs() {
static queue < int > Q;
memset(dep, 0, sizeof dep);
dep[s] = 1, Q.push(s);
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i];
if (dep[v] == 0 && cap[i] > 0)
dep[v] = dep[u] + 1, Q.push(v);
}
}
return dep[t] > 0;
} inline int dfs(int u, int flow) {
if (u == t) return flow;
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i];
if (dep[v] == dep[u] + 1 && cap[i] > 0) {
int res = dfs(v, min(flow, cap[i]));
if (res) { cap[i] -= res, cap[i ^ 1] += res; return res; }
}
}
return 0;
} inline int Dinic() {
int res = 0;
while (bfs()) while (int d = dfs(s, INF)) res += d;
return res;
} inline bool check(int mid) {
s = 0, t = n + 1;
tot = 1, memset(head, 0, sizeof head);
for (rg int i = 1; i <= m; ++i) {
if (g[i].c > mid) return 0;
if (g[i].d <= mid) link(g[i].a, g[i].b, 1);
}
for (rg int i = 1; i <= n; ++i) {
if (dgr[i] < 0) link(s, i, -dgr[i] / 2);
if (dgr[i] > 0) link(i, t, dgr[i] / 2);
}
return Dinic() == liu / 2;
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n), read(m);
for (rg int i = 1; i <= m; ++i) {
read(g[i].a), read(g[i].b), read(g[i].c), read(g[i].d);
if (g[i].c > g[i].d)
swap(g[i].a, g[i].b), swap(g[i].c, g[i].d);
--dgr[g[i].a], ++dgr[g[i].b];
}
for (rg int i = 1; i <= n; ++i) {
if (dgr[i] % 2 != 0) return puts("NIE"), 0;
liu += abs(dgr[i]) / 2;
}
int l = 1, r = 1000;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}

完结撒花 \(qwq\)

「POI2010」Bridges的更多相关文章

  1. 「POI2010」反对称 Antisymmetry (manacher算法)

    # 2452. 「POI2010」反对称 Antisymmetry [题目描述] 对于一个 $0/1$ 字符串,如果将这个字符串 $0$ 和 $1$ 取反后,再将整个串反过来和原串一样,就称作「反对称 ...

  2. LOJ#2452. 「POI2010」反对称 Antisymmetry

    题目描述 对于一个 \(0/1\) 字符串,如果将这个字符串 \(0\) 和 \(1\) 取反后,再将整个串反过来和原串一样,就称作「反对称」字符串.比如 \(00001111\) 和 \(01010 ...

  3. LOJ#2427. 「POI2010」珍珠项链 Beads

    题目地址 题目链接 题解 不会算复杂度真是致命,暴力枚举k每次计算是n/2+n/3+n/4+...+1的,用调和级数算是\(O(nlogn)\)的... 如果写哈希表的话能够\(O(nlogn)\), ...

  4. loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治

    loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...

  5. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  6. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  7. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  8. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  9. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

随机推荐

  1. NOIP2012 疫情控制 题解(LuoguP1084)

    NOIP2012 疫情控制 题解(LuoguP1084) 不难发现,如果一个点向上移动一定能控制更多的点,所以可以二分时间,判断是否可行. 但根节点不能不能控制,存在以当前时间可以走到根节点的点,可使 ...

  2. C语言 fgets

    C语言 fgets #include <stdio.h> char *fgets(char *s, int size, FILE *stream); 功能:从stream指定的文件内读入字 ...

  3. vue中mixins的理解及应用

    vue中mixins的理解及应用 vue中提供了一种混合机制--mixins,用来更高效的实现组件内容的复用.最开始我一度认为这个和组件好像没啥区别..后来发现错了.下面我们来看看mixins和普通情 ...

  4. DB技能数据库里把技能伤害调整

    1. MagID 技能代号 2. MagName 技能名称 3. Effect Type 效果类型(使用技能时角色的动作效果) 4. Effect 效果(技能产生的动画效果) 5. Spell 每次耗 ...

  5. Oracle中的数据迁移到Mysql数据库中的方式Navicat premium工具

    1.安装 Navicat premium工具 2.破解 Navicat premium工具 3.连接需要相互迁移的两个库Mysql和Oracle(可以是远程的或者本机的数据库都是可以的) 4.连接上之 ...

  6. spring cloud config 连接GitHub访问 报错 Cannot clone or checkout repository

    原因是建立仓库的时候将仓库私有化了,将仓库公有 或者 设置账号密码即可!

  7. jquery获取select多选框选中的文本值

    $("#select option:selected").text();

  8. 【网易官方】极客战记(codecombat)攻略-地牢-循环又循环

    关卡连接: https://codecombat.163.com/play/level/loop-da-loop 循环真是救命恩人! 简介: 你只需要 一个 while true循环 加上 4 条语句 ...

  9. 如何在linux安装ruby2.2.2+

    背景: 想搭建redis集群但是提示需要ruby2.2.2+ 直接使用yum安装 yum -y install ruby ruby-devel rubygems rpm-build 使用ruby -v ...

  10. 「题解」「BZOJ-4668」冷战

    题目 点这里 思路及代码 我们可以使用并查集的按秩合并(但是不要路径压缩). 两个集合被合并起来,连上的边的权值就设为当前时间. 然后我们可以发现,询问 \(j\) 与 \(k\) 何时联通,就是查询 ...