先跑网络流, 然后在残余网络tarjan缩点.

考虑一条边(u,v):

当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明

当且仅当scc[u] = scc[S] && scc[v] == scc[T], (u, v) 必定出现在最小割中. 这个很好脑补, 假如这条边不是满流, 那么S-T就存在增广路了..

------------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<stack>
 
using namespace std;
 
const int maxn = 4009;
const int maxm = 60009;
const int INF = 10000000;
 
struct edge {
int to, id, cap;
edge *next, *rev;
} E[maxm << 1], *head[maxn], *pt = E;
 
inline void add(int u, int v, int w, int id) {
pt->to = v; pt->cap = w; pt->id = id;
pt->next = head[u]; head[u] = pt++;
}
inline void addedge(int u, int v, int w, int id) {
add(u, v, w, id); add(v, u, 0, -1);
head[u]->rev = head[v];
head[v]->rev = head[u];
}
 
edge *p[maxn], *cur[maxn];
int h[maxn], cnt[maxn], ans[maxm][2], N, S, T;
stack<int> sta;
int dfn[maxn], low[maxn], scc[maxn], CK = 0, n = 0;
 
void maxFlow() {
memset(h, 0, sizeof h);
memset(cnt, 0, sizeof cnt);
for(int i = 0; i < N; i++) cur[i] = head[i];
cnt[0] = N;
edge* e;
for(int x = S, A = INF; h[S] < N; ) {
   for(e = cur[x]; e; e = e->next)
   if(e->cap && h[e->to] + 1 == h[x]) break;
if(e) {
A = min(A, e->cap);
p[e->to] = cur[x] = e;
x = e->to;
if(x == T) {
for(; x != S; x = p[x]->rev->to) {
p[x]->cap -= A;
p[x]->rev->cap += A;
}
A = INF;
x = S;
}
} else {
if(!--cnt[h[x]]) break;
h[x] = N;
for(e = head[x]; e; e = e->next) if(h[e->to] + 1 < h[x] && e->cap) {
h[x] = h[e->to] + 1;
cur[x] = e;
}
++cnt[h[x]];
if(x != S) x = p[x]->rev->to;
}
}
}
 
void tarjan(int x) {
dfn[x] = low[x] = CK++;
sta.push(x);
for(edge* e = head[x]; e; e = e->next) if(e->cap) {
if(!~dfn[e->to])
   tarjan(e->to), low[x] = min(low[x], low[e->to]);
else if(!~scc[e->to]) 
   low[x] = min(low[x], dfn[e->to]);
}
if(dfn[x] == low[x]) {
int t;
do {
t = sta.top(); sta.pop();
scc[t] = n;
} while(t != x);
n++;
}
}
 
int main() {
int m;
scanf("%d%d%d%d", &N, &m, &S, &T); S--; T--;
for(int i = 0; i < m; i++) {
int u, v, c; scanf("%d%d%d", &u, &v, &c); u--; v--;
addedge(u, v, c, i);
}
maxFlow();
memset(dfn, -1, sizeof dfn);
memset(low, -1, sizeof low);
memset(scc, -1, sizeof scc);
for(int i = 0; i < N; i++) if(!~dfn[i]) tarjan(i);
for(int i = 0; i < N; i++)
   for(edge* e = head[i]; e; e = e->next) if(~e->id && !e->cap) {
    if(scc[i] != scc[e->to]) ans[e->id][0] = 1;
    if(scc[i] == scc[S] && scc[e->to] == scc[T]) ans[e->id][1] = 1;
   }
for(int i = 0; i < m; i++)
   printf("%d %d\n", ans[i][0], ans[i][1]);
return 0;
}

------------------------------------------------------------------------------------

1797: [Ahoi2009]Mincut 最小割

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1476  Solved: 624
[Submit][Status][Discuss]

Description

A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路。设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路,需要代价ci。现在B国想找出一个路径切断方案,使中转站s不能到达中转站t,并且切断路径的代价之和最小。 小可可一眼就看出,这是一个求最小割的问题。但爱思考的小可可并不局限于此。现在他对每条单向道路提出两个问题: 问题一:是否存在一个最小代价路径切断方案,其中该道路被切断? 问题二:是否对任何一个最小代价路径切断方案,都有该道路被切断? 现在请你回答这两个问题。

Input

第一行有4个正整数,依次为N,M,s和t。第2行到第(M+1)行每行3个正 整数v,u,c表示v中转站到u中转站之间有单向道路相连,单向道路的起点是v, 终点是u,切断它的代价是c(1≤c≤100000)。 注意:两个中转站之间可能有多条道路直接相连。 同一行相邻两数之间可能有一个或多个空格。

Output

对每条单向边,按输入顺序,依次输出一行,包含两个非0即1的整数,分 别表示对问题一和问题二的回答(其中输出1表示是,输出0表示否)。 同一行相邻两数之间用一个空格隔开,每行开头和末尾没有多余空格。

Sample Input

6 7 1 6
1 2 3
1 3 2
2 4 4
2 5 1
3 5 5
4 6 2
5 6 3

Sample Output

1 0
1 0
0 0
1 0
0 0
1 0
1 0

HINT

设第(i+1)行输入的边为i号边,那么{1,2},{6,7},{2,4,6}是仅有的三个最小代价切割方案。它们的并是{1,2,4,6,7},交是 。 【数据规模和约定】 测试数据规模如下表所示 数据编号 N M 数据编号 N M 1 10 50 6 1000 20000 2 20 200 7 1000 40000 3 200 2000 8 2000 50000 4 200 2000 9 3000 60000 5 1000 20000 10 4000 60000

2015.4.16新加数据一组,可能会卡掉从前可以过的程序。

Source

BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )的更多相关文章

  1. BZOJ 1797: [Ahoi2009]Mincut 最小割

    1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2076  Solved: 885[Submit] ...

  2. ●BZOJ 1797 [Ahoi2009]Mincut 最小割

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1797 题解: 详细的讲解去看http://hzwer.com/3217.html首先跑一个最 ...

  3. bzoj 1797: [Ahoi2009]Mincut 最小割【tarjan+最小割】

    先跑一遍最大流,然后对残量网络(即所有没有满流的边)进行tarjan缩点. 能成为最小割的边一定满流:因为最小割不可能割一半的边: 连接s.t所在联通块的满流边一定在最小割里:如果不割掉这条边的话,就 ...

  4. bzoj 1797: [Ahoi2009]Mincut 最小割 (网络流)

    太神了直接看了hzwer的题解,有个新认识,一条路径上满流的一定是这条路径上所有边的最小值. type arr=record toward,next,cap,from:longint; end; co ...

  5. 1797: [Ahoi2009]Mincut 最小割

    1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...

  6. 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan

    题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...

  7. bzoj1797: [Ahoi2009]Mincut 最小割

    最大流+tarjan.然后因为原来那样写如果图不连通的话就会出错,WA了很久. jcvb: 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t] ...

  8. bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)

    1797: [Ahoi2009]Mincut 最小割 题目:传送门 题解: 感觉是一道肥肠好的题目. 第二问其实比第一问简单? 用残余网络跑强联通,流量大于0才访问. 那么如果两个点所属的联通分量分别 ...

  9. BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan

    BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...

随机推荐

  1. JQuery中回车键登陆

    //点击回车键 //王东升/2015/3/11 document.onkeydown = function (event) { var e = event ? event : (window.even ...

  2. Output in PowerShell

    Reference article: https://rkeithhill.wordpress.com/2007/09/16/effective-powershell-item-7-understan ...

  3. IOS 页面之间的传值(主讲delegate)

    IOS的Delegate,通俗一点说就是页面之间的传值. 总结一下现在知道的IOS页面之间传值的方式有三种 1.使用NSNotification发送通知的传值 主要是通过NSNotificationC ...

  4. C++模板:欧拉函数

    单个欧拉函数 int eular(int n){ int ret=1,i; for(i=2;i*i<=n;i++) if(n%i==0){ n/=i,ret*=i-1; while(n%i==0 ...

  5. 此windows副本不是正版解决方法

    老爸的win7今天黑屏 右下角出现 Windows7 内部版本7601 此windows副本不是正版 网上零散地找到了解决办法 写博汇总一下 我的情况是 电脑属性中的windows激活显示: 状态不可 ...

  6. Winter(bfs&&dfs)

    1084 - Winter   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Winter is ...

  7. C Looooops(扩展欧几里德)

    C Looooops Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) Total S ...

  8. One Person Game(扩展欧几里德求最小步数)

    One Person Game Time Limit: 2 Seconds      Memory Limit: 65536 KB There is an interesting and simple ...

  9. out/target/common/obj/PACKAGING/public_api.txt android.view.KeyEvent.KEYCODE_has changed value from

    编译出错: out/target/common/obj/PACKAGING/public_api.txt:22549: error 17: Field android.view.KeyEvent.KE ...

  10. hadoop学习;安装jdk,workstation虚拟机v2v迁移;虚拟机之间和跨物理机之间ping网络通信;virtualbox的centos中关闭防火墙和检查服务启动

    JDK 在Ubuntu下的安装 与 环境变量的配置 前期准备工作: 找到  JDK 和 配置TXT文件  并拷贝到桌面下  不是目录 而是文件拷贝到桌面下 以下的命令部分就直接复制粘贴就能够了 1.配 ...