传送门

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\)。小于零的情况同理。

最后判断是否满流即可。

细节注意事项

  • 细节有点多,要有耐心

参考代码

  1. #include <algorithm>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <cstdio>
  6. #include <cctype>
  7. #include <cmath>
  8. #include <ctime>
  9. #include <queue>
  10. #define rg register
  11. using namespace std;
  12. template < typename T > inline void read(T& s) {
  13. s = 0; int f = 0; char c = getchar();
  14. while (!isdigit(c)) f |= (c == '-'), c = getchar();
  15. while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
  16. s = f ? -s : s;
  17. }
  18. const int _ = 1010;
  19. const int __ = 5010 * 2 + 1010 * 2;
  20. const int INF = 2147483647;
  21. int tot = 1, head[_], nxt[__], ver[__], cap[__];
  22. inline void Add_edge(int u, int v, int d)
  23. { nxt[++tot] = head[u], head[u] = tot, ver[tot] = v, cap[tot] = d; }
  24. inline void link(int u, int v, int d) { Add_edge(u, v, d), Add_edge(v, u, 0); }
  25. int n, m, s, t, liu, dgr[_], dep[_];
  26. struct node{ int a, b, c, d; }g[__];
  27. inline int bfs() {
  28. static queue < int > Q;
  29. memset(dep, 0, sizeof dep);
  30. dep[s] = 1, Q.push(s);
  31. while (!Q.empty()) {
  32. int u = Q.front(); Q.pop();
  33. for (rg int i = head[u]; i; i = nxt[i]) {
  34. int v = ver[i];
  35. if (dep[v] == 0 && cap[i] > 0)
  36. dep[v] = dep[u] + 1, Q.push(v);
  37. }
  38. }
  39. return dep[t] > 0;
  40. }
  41. inline int dfs(int u, int flow) {
  42. if (u == t) return flow;
  43. for (rg int i = head[u]; i; i = nxt[i]) {
  44. int v = ver[i];
  45. if (dep[v] == dep[u] + 1 && cap[i] > 0) {
  46. int res = dfs(v, min(flow, cap[i]));
  47. if (res) { cap[i] -= res, cap[i ^ 1] += res; return res; }
  48. }
  49. }
  50. return 0;
  51. }
  52. inline int Dinic() {
  53. int res = 0;
  54. while (bfs()) while (int d = dfs(s, INF)) res += d;
  55. return res;
  56. }
  57. inline bool check(int mid) {
  58. s = 0, t = n + 1;
  59. tot = 1, memset(head, 0, sizeof head);
  60. for (rg int i = 1; i <= m; ++i) {
  61. if (g[i].c > mid) return 0;
  62. if (g[i].d <= mid) link(g[i].a, g[i].b, 1);
  63. }
  64. for (rg int i = 1; i <= n; ++i) {
  65. if (dgr[i] < 0) link(s, i, -dgr[i] / 2);
  66. if (dgr[i] > 0) link(i, t, dgr[i] / 2);
  67. }
  68. return Dinic() == liu / 2;
  69. }
  70. int main() {
  71. #ifndef ONLINE_JUDGE
  72. freopen("in.in", "r", stdin);
  73. #endif
  74. read(n), read(m);
  75. for (rg int i = 1; i <= m; ++i) {
  76. read(g[i].a), read(g[i].b), read(g[i].c), read(g[i].d);
  77. if (g[i].c > g[i].d)
  78. swap(g[i].a, g[i].b), swap(g[i].c, g[i].d);
  79. --dgr[g[i].a], ++dgr[g[i].b];
  80. }
  81. for (rg int i = 1; i <= n; ++i) {
  82. if (dgr[i] % 2 != 0) return puts("NIE"), 0;
  83. liu += abs(dgr[i]) / 2;
  84. }
  85. int l = 1, r = 1000;
  86. while (l < r) {
  87. int mid = (l + r) >> 1;
  88. if (check(mid)) r = mid;
  89. else l = mid + 1;
  90. }
  91. printf("%d\n", l);
  92. return 0;
  93. }

完结撒花 \(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. 操作系統3-內存管理(Linux內存管理)

    操作系統3-內存管理(Linux系統的內存管理方法) 9.Linux系統的內存管理方法 Linux採用"按需調頁"算法,支持三層管理策略.由於Intel CPU在硬件級提供了段式存 ...

  2. C#的HttpModule中及Java的Servlet中成员变量乱用导致的不易重现的BUG

    3年前写的在HttpModule中记录访问日志的代码,在最近使用日志数据分析登录账号的IP情况时,才发现了一个不易重现的BUG——日志中记录的登录账号出现串掉的情况.之所以这个时候才发现该问题,是因为 ...

  3. git创建远程分支并推送

    1.查看所有分支(-a=>'查看全部的分支') git branch -a 2.创建本地test分支 git branch test 2.2切换test分支 git checkout test ...

  4. codeforce F - Three Paths on a Tree

    F. Three Paths on a Tree time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  5. 【Html】Html基本标记

    <!doctype html> <html> <head> <!--mata 元信息标记--> <meta charset="utf-8 ...

  6. php 利用debug_backtrace方法跟踪代码调用

    在开发过程中,例如要修改别人开发的代码或调试出问题的代码,需要对代码流程一步步去跟踪,找到出问题的地方进行修改.如果有一个方法可以获取到某段代码是被哪个方法调用,并能一直回溯到最开始调用的地方(包括调 ...

  7. docker为镜像添加SSH服务

    启动并进入容器中 这里用db1容器完成实验. 安装openssh服务和修改sshd配置文件 安装openssh yum install openssh-server openssh-clients - ...

  8. sublime 最常用的快捷键.gif

    Ctrl+D 把光标放在文本上,按下⌘+ D将选择这个文本.多次按下⌘+ D则会增加匹配项 Alt+F3 会选中光标所在文本的所有匹配项 Ctrl+Shift+' 这是一个法宝,也许你希望所有的属性保 ...

  9. 【原】接口mock作用

    1.前后端 接口定义完成 并发开工 2.测试拿到mock接口 编写用例 3.mock接口 模拟异常服务器返回值 500 404 4.mock接口 模拟数据 不修改线上数据库

  10. 逻辑运算符及其优先级,C语言逻辑运算符及其优先级详解

    C 语言提供了以下三种逻辑运算符. 一元:!(逻辑非). 二元:&&(逻辑与).||(逻辑或). 以上三种逻辑运算符中,逻辑非 ! 的优先级最高,逻辑与 && 次之,逻 ...