【 bzoj 1797 】[Ahoi2009]Mincut 最小割 - 经典题
来源:互联网 发布:obs直播软件obsplus 编辑:程序博客网 时间:2024/05/22 12:57
这个题就是要求一条边在最小割里面的充分条件和必要条件。
首先考虑第一问,也即求充分条件。
我们先对这个图进行最大流算法得到任意一个最小割。设这个时候的残量网络为
可以证明,第一类点一定会被归为最小割中的
考虑一条满流边
这样我们就可以对残量网络缩点,对每条满流边判断是否在同一个强联通分量内即可求出第一问。
对于第二问,因为割边连着
代码:
#include <bits/stdc++.h>using namespace std;#define rep(i,a,b) for (int i = a , _ = (b) ; i <= _ ; i ++)#define per(i,a,b) for (int i = a , _ = (b) ; i >= _ ; i --)#define fore(i,u) for (int i = head[u] ; i ; i = nxt[i])inline int rd() { char c = getchar(); while (!isdigit(c)) c = getchar() ; int x = c - '0'; while (isdigit(c = getchar())) x = x * 10 + c - '0'; return x;}inline void upmin(int&a , int b) { if (a > b) a = b ; }const int maxn = 5007;const int maxm = 120007;const int inf = 0x7fffffff;typedef int arr[maxn];typedef int adj[maxm];arr head , belong , dis , pos , low , cur;adj fr , to , nxt , cap , flow;int n , m , S , T , ett , scc_cnt , dfs_clock;stack<int> s;queue<int> Q;inline void ins(int u , int v , int c) { fr[++ ett] = u , to[ett] = v , nxt[ett] = head[u] , cap[ett] = c , head[u] = ett; fr[++ ett] = v , to[ett] = u , nxt[ett] = head[v] , cap[ett] = 0 , head[v] = ett;}void input() { ett = 1; n = rd() , m = rd() , S = rd() , T = rd(); rep (i , 1 , m) { int u = rd() , v = rd() , w = rd(); ins(u , v , w); }}bool bfs() { rep (i , 1 , n) dis[i] = inf; dis[S] = 0 , Q.push(S); while (!Q.empty()) { int u = Q.front() ; Q.pop(); fore (i , u) { int v = to[i]; if (dis[v] == inf && cap[i] > flow[i]) dis[v] = dis[u] + 1 , Q.push(v); } } return dis[T] != inf;}int dfs(int u , int a) { if (u == T || !a) return a; int ret = 0 , f; for (int&i = cur[u] ; i ; i = nxt[i]) { int v = to[i]; if (dis[v] == dis[u] + 1 && (f = dfs(v , min(a , cap[i] - flow[i]))) > 0) { flow[i] += f , flow[i ^ 1] -= f , ret += f , a -= f; if (!a) break; } } return ret;}void tarjan(int u , int p) { pos[u] = low[u] = ++ dfs_clock; s.push(u); fore (i , u) if (cap[i] > flow[i]) { int v = to[i];// printf("%d %d\n" , u , v); if (!pos[v]) { tarjan(v , u); upmin(low[u] , low[v]); } else if (!belong[v]) upmin(low[u] , pos[v]); } if (low[u] == pos[u]) { scc_cnt ++; for (;;) { int x = s.top() ; s.pop(); belong[x] = scc_cnt; if (x == u) break; } }}void solve() { int mx_flow = 0; while (bfs()) { rep (i , 1 , n) cur[i] = head[i]; mx_flow += dfs(S , inf); } rep (u , 1 , n) if (!pos[u]) tarjan(u , 0); rep (i , 1 , m) { int u = fr[i << 1] , v = to[i << 1] , f = (flow[i << 1] == cap[i << 1]); printf("%d%c" , belong[u] != belong[v] && f , ' '); printf("%d%c" , belong[u] == belong[S] && belong[v] == belong[T] , '\n'); }}int main() { #ifndef ONLINE_JUDGE freopen("data.txt" , "r" , stdin); #endif input(); solve(); return 0;}
0 0
- 【 bzoj 1797 】[Ahoi2009]Mincut 最小割 - 经典题
- bzoj 1797: [Ahoi2009]Mincut 最小割
- 【BZOJ 1797】 [Ahoi2009]Mincut 最小割
- BZOJ 1797 [Ahoi2009]Mincut 最小割
- bzoj 1797: [Ahoi2009]Mincut 最小割
- bzoj 1797: [Ahoi2009]Mincut 最小割 (最小割+tarjan)
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- [BZOJ]1797: [Ahoi2009]Mincut 最小割 网络流+强连通
- [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割(from hzwer)
- [最小割唯一性 Tarjan] BZOJ 1797 [Ahoi2009]Mincut 最小割
- BZOJ 1797: [Ahoi2009]Mincut 最小割 图的联通 最小割 tarjan
- 边与最小割(bzoj 1797: [Ahoi2009]Mincut 最小割)
- 1797: [Ahoi2009]Mincut 最小割 最小割+tarjan
- BZOJ1797: [Ahoi2009]Mincut 最小割
- HDU 1709 The Balance(母函数)
- android面试2
- 数位DP 计划
- equals()和hashCode()的区别
- 48. Rotate Image LeetCode
- 【 bzoj 1797 】[Ahoi2009]Mincut 最小割 - 经典题
- 使用DDMS查看安卓程序本地文件的内容
- 网站复制
- Java认证考试实例疑难辨析(8)
- [MyBatis日记](4)映射语句
- (二)利用processing绘制自定义图像
- C语言中的 (void*)0 与 (void)0
- 11. Container With Most Water LeetCode
- 1032. 挖掘机技术哪家强