bzoj2095 Bridges
来源:互联网 发布:中国航空发动机 知乎 编辑:程序博客网 时间:2024/05/29 08:47
Bridges
题目背景:
bzoj2095
分析:今天get到一种新技能,混合图欧拉回路,首先我们来考虑下普通的有向图,当且仅当每一个点的入度等于出度时,存在一个欧拉回路,无向图则是每一个点的度数为偶数,现在我们考虑混合图,首先对于有向边直接选择,对于无向边,我们随便定向,之后如果原图存在欧拉回路,那么每一个点的入度和出度之差一定是偶数(若有一条边方向相反,则会有两个点的入度和出度之差的绝对值加2),考虑调整的方式,我们选择网络流,对于每一个入度大于出度的点,从源点向当前点连接边权为(入度 – 出度)/ 2的边,对于每一个出度大于入度的点,从当前点向汇点连边权为(出度 – 入度)/ 2的边,对于每一条我们定过向的无向边,反向连一条边权为1的边,表示经过一次这条边就表示将这条有向边反向,调整2的入度和出度。然后直接二分能够承受的风力大小,建图跑最大流,判断获得的最大流是否为之前连向起点的权值和,若满足则存在否则不存在。注意原图可能不连通,所以我还搞了个并查集,事实上应该不用······
Source:
/* created by scarlyw*/#include <cstdio>#include <string>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>#include <cctype>#include <vector>#include <set>#include <queue> inline char read() { static const int IN_LEN = 1024 * 1024; static char buf[IN_LEN], *s, *t; if (s == t) { t = (s = buf) + fread(buf, 1, IN_LEN, stdin); if (s == t) return -1; } return *s++;} ///*template<class T>inline void R(T &x) { static char c; static bool iosig; for (c = read(), iosig = false; !isdigit(c); c = read()) { if (c == -1) return ; if (c == '-') iosig = true; } for (x = 0; isdigit(c); c = read()) x = ((x << 2) + x << 1) + (c ^ '0'); if (iosig) x = -x;}//*/ const int OUT_LEN = 1024 * 1024;char obuf[OUT_LEN], *oh = obuf;inline void write_char(char c) { if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf; *oh++ = c;} template<class T>inline void W(T x) { static int buf[30], cnt; if (x == 0) write_char('0'); else { if (x < 0) write_char('-'), x = -x; for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48; while (cnt) write_char(buf[cnt--]); }} inline void flush() { fwrite(obuf, 1, oh - obuf, stdout);} /*template<class T>inline void R(T &x) { static char c; static bool iosig; for (c = getchar(), iosig = false; !isdigit(c); c = getchar()) if (c == '-') iosig = true; for (x = 0; isdigit(c); c = getchar()) x = ((x << 2) + x << 1) + (c ^ '0'); if (iosig) x = -x;}//*/ const int MAXN = 1000 + 10;const int INF = ~0u >> 1; struct node { int to, w, f, rev; node(int to = 0, int w = 0, int rev = 0) : to(to), w(w), f(0), rev(rev) {}} ; struct edge { int a, b, c, d; edge(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {}} edges[MAXN << 1]; std::vector<node> edge[MAXN]; int n, m, a, b, c, d, s, t;int dis[MAXN], temp[MAXN], gap[MAXN], father[MAXN];int out_degree[MAXN], in_degree[MAXN]; inline void add_edge(int x, int y, int w) { edge[x].push_back(node(y, w, edge[y].size())); edge[y].push_back(node(x, 0, edge[x].size() - 1));} inline void read_in() { R(n), R(m), s = 0, t = n + 1; for (int i = 1; i <= m; ++i) R(edges[i].a), R(edges[i].b), R(edges[i].c), R(edges[i].d); }inline int sap(int cur, int flow, int s, int t, int n) { if (cur == t) return flow; int del = 0; static int temp[MAXN]; for (int p = temp[cur]; p < edge[cur].size(); ++p) { node *e = &edge[cur][p]; if (e->w > 0 && dis[e->to] + 1 == dis[cur]) { int ret = sap(e->to, std::min(e->w, flow - del), s, t, n); e->w -= ret, edge[e->to][e->rev].w += ret, temp[cur] = p; if ((del += ret) == flow || dis[cur] >= n) return temp[cur] = 0, del; } } if (--gap[dis[cur]] == 0) dis[s] = n; gap[++dis[cur]]++, temp[cur] = 0; return del;} inline int sap(int s, int t, int n) { int ret = 0; memset(gap, 0, sizeof(int) * (n + 1)); memset(dis, 0, sizeof(int) * (n + 1)); for (gap[0] = n; dis[s] < n; ) ret += sap(s, ~0u >> 1, s, t, n); return ret;} inline int get_father(int x) { return (father[x] == x) ? x : (father[x] = get_father(father[x]));} inline void unite(int x, int y) { int fa1 = get_father(x), fa2 = get_father(y); if (fa1 != fa2) father[fa1] = fa2;} inline bool check(int mid) { for (int i = 0; i <= n + 1; ++i) edge[i].clear(), father[i] = i, in_degree[i] = 0, out_degree[i] = 0; for (int i = 1; i <= m; ++i) { int u = edges[i].a, v = edges[i].b; if (edges[i].c <= mid && edges[i].d <= mid) out_degree[u]++, in_degree[v]++, add_edge(v, u, 1), unite(u, v); else if (edges[i].c <= mid) out_degree[u]++, in_degree[v]++, unite(u, v); else if (edges[i].d <= mid) out_degree[v]++, in_degree[u]++, unite(u, v); } int ans = 0, fa = get_father(1), tt = 0; for (int i = 1; i <= n; ++i) { if (get_father(i) != fa) return false; int x = in_degree[i] - out_degree[i]; if (abs(x) & 1) return false; if (x > 0) add_edge(s, i, x / 2), ans += x / 2; else if (x < 0) add_edge(i, t, -x / 2), tt -= x / 2; } return (sap(s, t, t + 1) == ans);} inline void binary() { int l = -1, r = 1000 + 1; while (l + 1 < r) { int mid = l + r >> 1; check(mid) ? (r = mid) : (l = mid); } if (r == 1000 + 1) std::cout << "NIE"; else std::cout << r;} int main() {// freopen("data.in", "r", stdin);// freopen("data.out", "w", stdout); read_in(); binary(); return 0;}
阅读全文
0 0
- bzoj2095 Bridges
- bzoj2095【POI2010】Bridges
- bzoj2095 [Poi2010]Bridges
- BZOJ2095: [Poi2010]Bridges
- BZOJ2095[Poi2010] Bridges
- bzoj2095 bridges 【网络流判欧拉回路】
- bzoj2095: [Poi2010]Bridges 二分+最大流
- 图论欧拉回路初步 & BZOJ2095 POI2010 Bridges
- 【BZOJ2095】【最大流】[Poi2010]Bridges 题解
- Bzoj2095:[Poi2010]Bridges:混合图欧拉回路,网络流
- [BZOJ2095][Poi2010]Bridges(二分+最大流+欧拉图)
- [BZOJ2095]-[Poi2010]Bridges-二分答案+混合图欧拉回路判定
- BZOJ2095 bridge
- gym Bridges
- 【XSY2024】【BZOJ2095】【POI2010】Bridge 网络流
- Bridges of Friendship
- [pku2288]Islands and Bridges
- EAI Bridges简介
- 1134. Vertex Cover (25)-PAT甲级真题
- 安卓自定义AlertDialog弹出框
- django中render()与render_to_response()区别
- socket服务器开发中的SO_REUSEADDR选项与让人心烦的TIME_WAIT
- 1135. Is It A Red-Black Tree (30)-PAT甲级真题
- bzoj2095 Bridges
- mysql update 多表
- css pointer-events属性
- httpClient工具类
- 编程中的幂等性 —— HTTP幂等性
- redis for windows 搭建集群
- ubuntu ssh远程连接失败问题
- 路由器的虚拟服务器设置
- 用Redis实现导出功能