[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
原创粉丝点击