[BZOJ1797][Ahoi2009]Mincut 最小割 && 最小割+强连通
来源:互联网 发布:数据库完整性约束范例 编辑:程序博客网 时间:2024/05/16 16:18
先跑一遍最大流 然后在残余网络里面跑强连通 跑完过后对于每一条满流边的两个端点u, v
检验他们所在的强连通分量
若SCC[u] != SCC[v] 则这条边至少存在于一个最小割方案中
若SCC[u] != SCC[v] 并且 SCC[u] == SCC[S] && SCC[v] == SCC[T] 那么这一条边一定在任何一个最小割方案中
#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 4000;const int MAXM = 60000;const int INF = 0x3f3f3f3f;int n, m, S, T;int dfn[MAXN+10], low[MAXN+10], dcnt, scc, SCC[MAXN+10];int sta[MAXN+10], top;int val[MAXM+10];struct Node {int u, v, c, next, id;};struct ISAP {int gap[MAXN+10], d[MAXN+10];int adj[MAXN+10], ecnt;Node Edge[MAXM*2+10];int n, s, t;void init() {memset(adj, -1, sizeof(adj));}void addedge(int u, int v, int c, int id) {Node &e = Edge[ecnt];e.v = v; e.u = u; e.c = c; e.id = id; e.next = adj[u]; adj[u] = ecnt++;}void add(int u, int v, int c, int id) {addedge(u, v, c, id);addedge(v, u, 0, id);}void init_dis() {queue <int> q;memset(d, 0, sizeof(d));memset(gap, 0, sizeof(gap));q.push(t);while(!q.empty()) {int u = q.front(); q.pop();gap[d[u]]++;for(int i = adj[u]; ~i; i = Edge[i].next) {int v = Edge[i].v;if(!d[v] && v != t) d[v] = d[u] + 1, q.push(v);}}}int aug(int u, int inc) {int Inc = 0, mindis = n-1;if(u == t) return inc;for(int i = adj[u]; ~i; i = Edge[i].next) {Node &e = Edge[i];int v = e.v, c = e.c;if(c) {if(d[v] == d[u] - 1) {int del = min(c, inc - Inc);del = aug(v, del);Inc += del;Edge[i].c -= del;Edge[i^1].c += del;if(d[s] >= n) return Inc;if(inc == Inc) return inc;}mindis = min(mindis, d[v]);}}if(!Inc) {gap[d[u]]--;if(gap[d[u]] == 0) d[s] = n;d[u] = mindis + 1;gap[d[u]]++;}return Inc;}int Maxflow(int _s, int _t, int _n) {s = _s; t = _t; n = _n;int ret = 0;init_dis();while(d[s] < n) ret += aug(s, INF);return ret;}void dfs(int u) {low[u] = dfn[u] = ++dcnt;sta[++top] = u;for(int i = adj[u]; ~i; i = Edge[i].next) {Node &e = Edge[i];int v = e.v, c = e.c;if(!c) continue ;if(!dfn[v]) { dfs(v); low[u] = min(low[v], low[u]);}else if(!SCC[v]) low[u] = min(low[u], dfn[v]);}if(low[u] == dfn[u]) {int x;scc++;do {x = sta[top--];SCC[x] = scc;} while(x != u);}}void build() {for(int u = 1; u <= n; u++)for(int i = adj[u]; ~i; i = Edge[i].next) {Node &e = Edge[i];int v = e.v, c = e.c;if((i & 1) == 0 && c == 0) {if(SCC[u] != SCC[v]) {if(SCC[u] == SCC[S] && SCC[v] == SCC[T])val[e.id] = 2;else val[e.id] = 1;}}}}} sap;void find_scc() {for(int i = 1; i <= n; i++) if(!dfn[i]) sap.dfs(i);sap.build();}int main() {sap.init();SF("%d%d%d%d", &n, &m, &S, &T);for(int i = 1; i <= m; i++) {int u, v, c; SF("%d%d%d", &u, &v, &c);sap.add(u, v, c, i);}sap.Maxflow(S, T, n);find_scc();for(int i = 1; i <= m; i++)if(val[i] == 2) puts("1 1");else if(val[i] == 1) puts("1 0");else puts("0 0");}
0 0
- [BZOJ1797][Ahoi2009]Mincut 最小割 && 最小割+强连通
- [BZOJ1797][AHOI2009][最大流][强连通分量]Mincut最小割
- bzoj1797 [Ahoi2009]Mincut 最小割 网络流+强连通分量
- BZOJ1797: [Ahoi2009]Mincut 最小割
- BZOJ1797: [Ahoi2009]Mincut 最小割
- BZOJ1797: [Ahoi2009]Mincut 最小割
- bzoj1797: [Ahoi2009]Mincut 最小割
- 【bzoj1797】[Ahoi2009]Mincut 最小割
- bzoj1797: [Ahoi2009]Mincut 最小割
- Bzoj1797 ahoi2009最小割
- [bzoj1797][AHOI2009]最小割
- [BZOJ]1797: [Ahoi2009]Mincut 最小割 网络流+强连通
- [Ahoi2009]Mincut 最小割
- [BZOJ1797][Ahoi2009]Mincut 最小割 做题笔记
- 【bzoj1797】[Ahoi2009]Mincut 最小割 最小割的可行边与必须边
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- Android AsyncTask异步处理
- linu 查看网络状态端口占用情况
- 蓝桥杯 概率问题 递归概率计算
- iOS开发之类别、扩展
- Java中的Map List Set等集合类
- [BZOJ1797][Ahoi2009]Mincut 最小割 && 最小割+强连通
- TypeReference -- 让Jackson Json在List/Map中识别自己的Object
- linux ftok()函数
- Andriod Studio 检测不到Device解决方案
- zhcon解决Ubuntu命令行模式乱码问题
- IOS中常用的四种数据持久化方法
- d导入新项目后出现:Unable to resolve target 'android-19'
- Android 多内存卡获取 外部内存卡路径
- 用MATLAB生成mif文件