BZOJ2095 [Poi2010]Bridges

首先二分答案。。。然后这张图变成了有一些有向边,有一些无向边

然后就是混合图欧拉回路的判断

我们知道如果是有向图,它存在欧拉回路的等价条件是所有点的出度等于入度

对于混合图。。。先不管有向边,把无向边随意定向

首先要满足条件就是当前图的点的度数都是偶数,因为把一条边反向端点的出度入度之差改变了2,奇偶性不变

我们只要判断是否把部分已经定向的无向边反向以后可以满足度都是偶数这个条件

用网络流来判断

对于每条边,如果定向为$x$到$y$,则$y$向$x$连边,流量为1

对于每个点$x$,如果出度 - 入度大于0,源点向$x$连边,否则$x$向汇点连边,流量为度数差除以2

如果满流则说明可以

  1 /**************************************************************
  2     Problem: 2095
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:136 ms
  7     Memory:952 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13
 14 using namespace std;
 15 const int N = 1e3 + 5;
 16 const int M = 2e3 + 5;
 17 const int inf = 1e9;
 18
 19 inline int read();
 20
 21 struct Edge {
 22     int x, y;
 23     int v1, v2;
 24
 25     inline void get() {
 26         x = read(), y = read(), v1 = read(), v2 = read();
 27         if (v1 > v2) swap(x, y), swap(v1, v2);
 28     }
 29 } E[M];
 30
 31 struct edge {
 32     int next, to, f;
 33     edge() {}
 34     edge(int _n, int _t, int _f) : next(_n), to(_t), f(_f) {}
 35 } e[M << 2];
 36
 37 int n, m, S, T;
 38 int first[N], tot;
 39 int deg[N], tot_deg;
 40 int d[N];
 41
 42 inline void Add_Edges(int x, int y, int f) {
 43     e[++tot] = edge(first[x], y, f), first[x] = tot;
 44     e[++tot] = edge(first[y], x, 0), first[y] = tot;
 45 }
 46
 47 #define y e[x].to
 48 #define p q[l]
 49 bool bfs() {
 50     static int l, r, x, q[N];
 51     memset(d, -1, sizeof(d));
 52     d[q[1] = S] = 1;
 53     for (l = r = 1; l != r + 1; ++l)
 54         for (x = first[p]; x; x = e[x].next)
 55             if (!~d[y] && e[x].f) {
 56                 d[q[++r] = y] = d[p] + 1;
 57                 if (y == T) return 1;
 58             }
 59     return 0;
 60 }
 61 #undef p
 62
 63 int dfs(int p, int lim) {
 64   if (p == T || !lim) return lim;
 65   int x, tmp, rest = lim;
 66   for (x = first[p]; x && rest; x = e[x].next)
 67     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
 68       rest -= (tmp = dfs(y, tmp));
 69       e[x].f -= tmp, e[x ^ 1].f += tmp;
 70       if (!rest) return lim;
 71     }
 72   if (rest) d[p] = -1;
 73   return lim - rest;
 74 }
 75 #undef y
 76
 77 int Dinic() {
 78   static int res, i;
 79   for (res = 0, i = 1; i <= n; ++i)
 80         if (deg[i] & 1) return -1;
 81   while (bfs())
 82     res += dfs(S, inf);
 83   return res;
 84 }
 85
 86 void rebuild_graph(int t) {
 87     static int i;
 88     tot = 1, tot_deg = 0;
 89     for (i = 1; i <= n + 2; ++i)
 90         deg[i] = first[i] = 0;
 91     for (i = 1; i <= m; ++i) {
 92         if (E[i].v1 <= t) --deg[E[i].x], ++deg[E[i].y];
 93         if (E[i].v2 <= t) Add_Edges(E[i].y, E[i].x, 1);
 94     }
 95     for (i = 1; i <= n; ++i)
 96         if (deg[i] > 0) tot_deg += deg[i] >> 1, Add_Edges(S, i, deg[i] >> 1);
 97         else Add_Edges(i, T, (-deg[i]) >> 1);
 98 }
 99
100 int main() {
101     int i, l = inf, r = 0, tmp;
102     n = read(), m = read(), S = n + 1, T = S + 1;
103     for (i = 1; i <= m; ++i) {
104         E[i].get();
105         l = min(l, E[i].v1), r = max(r, E[i].v2);
106     }
107     l -= 1, tmp = (r += 1);
108 #define mid (l + r >> 1)
109     while (l + 1 < r) {
110         rebuild_graph(mid);
111         if (Dinic() == tot_deg) r = mid;
112         else l = mid;
113     }
114 #undef mid
115     if (tmp == r) puts("NIE");
116     else printf("%d\n", r);
117     return 0;
118 }
119
120 inline int read() {
121     static int x;
122     static char ch;
123     x = 0, ch = getchar();
124     while (ch < ‘0‘ || ‘9‘ < ch)
125         ch = getchar();
126     while (‘0‘ <= ch && ch <= ‘9‘) {
127         x = x * 10 + ch - ‘0‘;
128         ch = getchar();
129     }
130     return x;
131 }

时间: 2024-10-05 04:59:39

BZOJ2095 [Poi2010]Bridges的相关文章

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

传送门 这篇题解讲的真吼->这里 首先我们可以二分一个答案,然后把所有权值小于这个答案的都加入图中 那么问题就转化为一张混合图(既有有向边又有无向边)中是否存在欧拉回路 首先 无向图存在欧拉回路,当且仅当图的所有顶点度数都为偶数且图连通.        有向图存在欧拉回路,当且仅当图的所有顶点入度等于出度且图连通. 那么我们怎么判断混合图的欧拉回路是否存在呢? 我们把无向边的边随便定向,然后计算每一个点的入度和出度.如果有某一个点的入度和出度之差是奇数,那么肯定不存在欧拉回路. 因为欧拉回路要求

【BZOJ2095】[Poi2010]Bridges 动态加边网络流

[BZOJ2095][Poi2010]Bridges Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1出发,骑过每一座桥,到达每一个小岛,然后回到小岛1.霸中同学为了让YYD减肥成功,召唤了大风,由于是海上,风变得十分大,经过每一座桥都有不可避免的风阻碍YYD,YYD十分ddt,于是用泡芙贿赂了你,希望你能帮他找出一条承受的最大风力最小的路线.

BZOJ 2095: [Poi2010]Bridges

2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 869  Solved: 299[Submit][Status][Discuss] Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1出发,骑过每一座桥,到达每一个小岛,然后回到小岛1.霸中同学为了让YYD减

bzoj 2095 Poi2010 Bridges 混合图欧拉回路

二分答案后变为判定混合图是否存在欧拉回路. 有向图存在欧拉回路的条件是连通且每个点的入=出. 把混合图先变为有向图后再修改. 首先把每条无向边定向,再在最大流图中建一条与定的方向反的流量为1的边. 每个点的 d=出度-入度 必须是偶数,因为把一条边反向后这个东西至少会会改变2. 然后由S向 d<0的连流量-d/2的边,d>0的向T连d/2的边. 有欧拉回路的条件是满流. 1 #include<iostream> 2 #include<cstdio> 3 #include

BZOJ 2095 Poi2010 Bridges 二分答案+网络流

题目大意:给定一张图,每条边的两个方向有两个不同的权值,现在要求从1号节点出发遍历每条边一次且仅一次,最后回到1号节点,求最大边权的最小值 谁TM翻译的这道题给我滚出来看我不打死你 二分最大边的权值,然后就是经典的判断混合图欧拉回路存在性的问题了 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 2020 #define S 0 #d

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

[题意] 给定n点m边的无向图,对于边u,v,从u到v边权为c,从v到u的边权为d,问能够经过每条边一次且仅一次的最小权值和. [思路] 二分答案mid,然后切断权值大于mid的边,原图就变成了一个既有无向边又有有向边的混合图,则问题转化为求混合图上是否存在一个欧拉回路. 无向图存在欧拉回路,当且仅当图的所有顶点度数都为偶数且图连通.      有向图存在欧拉回路,当且仅当图的所有顶点入度等于初度且图连通. 一条边仅经过一次,所以无向边最终的归属就是有向边,即我们要给无向边定向使存在欧拉回路.

[NetworkFlow]网络流建模相关

流 网络流问题本质上是线性规划问题的应用之一,线性规划问题的标准形式是给出一组等式约束和不等式约束,要求最优化一个线性函数. 在流问题中,变量以流量的形式出现在问题中,我们给出一个流网络(以有向图的形式)来解决有关流的问题. 流是整个网络流问题的核心所在,它实际上是定义在流网络上的一个线性函数,在流网络中,每条边都有一个流量f(u,v),流f=∑v∈Vf(S,v) 流量f(u,v)是流问题中的变量,它有两个约束,一个是不等式,一个是等式 (1)容量限制:f(u,v)≤c(u,v) (2)流量平衡

【BZOJ2095】【POI2010】Bridge 网络流

题目大意 ? 给你一个无向图,每条边的两个方向的边权可能不同.要求找出一条欧拉回路使得路径上的边权的最大值最小.无解输出"NIE". \(2\leq n\leq 1000,1\leq m\leq 2000\) 题解 ? 我们先二分答案\(ans\),把边权大于\(ans\)的边删掉. ? 现在图中还剩下一些有向边和一些无向边,也就是说这是一个混合图. ? 混合图的欧拉回路怎么求? ? 先把无向边定向(方向任意),求出每个点的出度\(d1_i\)和入度\(d2_i\).如果存在点\(i\

[BZOJ2095]Bridges

最大值最小,是二分 转化为判定问题:给定一个混合图,问是否存在欧拉回路 首先,有向图存在欧拉回路的充要条件是每个点的入度等于出度,现在我们有一个混合图,我们要做的就是给其中的无向边定向,使得它变成有向图之后存在欧拉回路 记点$x$的入度为$in_x$,出度为$out_x$,我们的目标是使得每个点$x$满足$in_x-out_x=0$ 先随便给每条无向边定向,这样不一定满足要求,所以我们必须让某些边反向,反向$a\rightarrow b$会让$in_a-out_a$增加$2$,让$in_b-ou