BZOJ 4435 [双连通分量][Hash]
来源:互联网 发布:知乎客户端电脑版下载 编辑:程序博客网 时间:2024/05/17 09:20
Description
你被雇佣升级一个旧果汁加工厂的橙汁运输系统。系统有管道和节点构成。每条管道都是双向的,且每条管道的流量都是
Solution
根据最大流最小割定理,我们要求的其实就是最小割。题中所说每个节点只会连出至多三条边,显然最小割至多为
若最小割为
若最小割为
若最小割为
如何判断删去任意一条边之后的双连通分量编号是否相同,只需要对每个点
时间复杂度
#include <cstdio>#include <cstring>#include <iostream>using namespace std;inline char get(void) { static char buf[100000], *S = buf, *T = buf; if (S == T) { T = (S = buf) + fread(buf, 1, 100000, stdin); if (S == T) return EOF; } return *S++;}inline void read(int &x) { static char c; x = 0; for (c = get(); c < '0' || c > '9'; c = get()); for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';}const int N = 3030;const int M = 4545;const int P = 2333333;typedef long long ll;struct edge { int to, next; edge (int t = 0, int n = 0):to(t), next(n) {}};edge G[M << 1];int pre[N], low[N], bcc[N], sta[N];int has[N], mark[M << 1], id[N];int head[N];int ans[N][N];int n, m, x, y, Gcnt, clc, top, Bcnt, cnt, Ans;inline int Min(int a, int b) { return a < b ? a : b;}inline void AddEdge(int from, int to) { G[++Gcnt] = edge(to, head[from]); head[from] = Gcnt; G[++Gcnt] = edge(from, head[to]); head[to] = Gcnt;}void dfs(int u, int fa) { low[u] = pre[u] = ++clc; int to; id[u] = cnt; sta[++top] = u; for (int i = head[u]; i; i = G[i].next) if (!mark[i]) { to = G[i].to; if (pre[to]) { if (to != fa) low[u] = Min(low[u], low[to]); } else if (to != fa) { dfs(to, u); low[u] = Min(low[u], low[to]); } } if (low[u] == pre[u]) { Bcnt++; while (sta[top] != u) { bcc[sta[top]] = Bcnt; top--; } bcc[sta[top--]] = Bcnt; }}void SetBcc(int flag = 0) { Bcnt = cnt = clc = top = 0; memset(pre, 0, sizeof pre); memset(id, 0, sizeof id); for (int i = 1; i <= n; i++) if (!pre[i]) { cnt++; dfs(i, 0); } if (flag) return (void)("%%%%gjghfd%%%%"); for (int i = 1; i <= n; i++) has[i] = ((ll)has[i] * M % P + bcc[i]) % P;}int main(void) { freopen("1.in", "r", stdin); freopen("1.out", "w", stdout); read(n); read(m); for (int i = 1; i <= m; i++) { read(x); read(y); AddEdge(x, y); } SetBcc(1); for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) { if (bcc[i] != bcc[j]) ans[i][j] = 1; if (id[i] != id[j]) ans[i][j] = -1; } for (int i = 1; i <= Gcnt; i += 2) { mark[i] = mark[i + 1] = 1; SetBcc(); mark[i] = mark[i + 1] = 0; } for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) { if (ans[i][j] != 0) continue; if (has[i] == has[j]) ans[i][j] = 3; else ans[i][j] = 2; } for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) if (ans[i][j] > 0) Ans += ans[i][j]; cout << Ans << endl; return 0;}
阅读全文
2 0
- BZOJ 4435 [双连通分量][Hash]
- [边双连通分量 Hash] BZOJ 4435 [Cerc2015]Juice Junctions
- BZOJ 3590 [双连通分量][状压DP]
- 双连通分量
- 双连通分量_road
- 边双连通分量
- 双连通分量
- 双连通分量-tarjan
- 双连通分量
- 双连通分量
- 双连通分量-tarjan
- 双连通分量
- poj3177 双连通分量
- 点双连通分量
- 双连通分量
- hdu3394Railway 双连通分量
- 点双连通分量
- 点双连通分量
- Struts2
- Linux系统编程:标准IO和文件IO的区别
- 四、程序的移植
- forward和redirect区别
- asm comm align
- BZOJ 4435 [双连通分量][Hash]
- [jzoj]1729. blockenemy(树形DP+详细分析)
- Qt5 中对 C++11 一些新特性的封装详解(二)
- (ubuntu 16.04) Git 本地仓库简单操作学习 (二)
- 2017WebStrom-Server激活
- 数据结构实验之链表九:双向链表
- Spring返回json字符串到前台乱码的解决办法
- android自定义圆形drawable
- JS事件处理程序