1797: [Ahoi2009]Mincut 最小割

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1072  Solved: 446
[Submit][Status]

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

Source

Day1

题解:摘自jcvb

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

一个有向图,源点s,汇点t,问哪些边能够出现在某个最小割集中,哪些边必定出现在最小割集中。

求最大流,在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号。显然有id[s]!=id[t](否则s到t有通路,能继续增广)。
①对于任意一条满流边(u,v),(u,v)能够出现在某个最小割集中,当且仅当id[u]!=id[v];
②对于任意一条满流边(u,v),(u,v)必定出现在最小割集中,当且仅当id[u]==id[s]且id[v]==id[t]。

简要写一下证明:
首先,由最大流最小割定理易知最小割中的割边一定是满流边。

==>如果id[u]==id[v],则残余网络存在u->v的通路,通过(u,v)的割也必然通过这条通路上的某条非满流边,不会是最小割。(update:QAQ后来发现这个证明有问题。。。到时候再想想)
<==将每个SCC缩成一个点,得到的新图就只含有满流边了。那么新图的任一s-t割都对应原图的某个最小割,从中任取一个把id[u]和id[v]割开的割即可证明。


<==:假设将(u,v)的边权增大,那么残余网络中会出现s->u->v->t的通路,从而能继续增广,于是最大流流量(也就是最小割容量)会增大。这即说明(u,v)是最小割集中必须出现的边。
==>:上面的证明可以反推回去,略。

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

结论是正确的,可以AC

代码:

  const inf=maxlongint;
type node=record
from,go,next,v:longint;
end;
var tot,i,j,n,m,maxflow,l,r,s,t,x,y,z,ti,top,cnt,xx,yy:longint;
h,head,q,cur,low,dfn,sta,scc:array[..] of longint;
e:array[..] of node;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure ins(x,y,z:longint);
begin
inc(tot);
e[tot].from:=x;e[tot].go:=y;e[tot].v:=z;e[tot].next:=head[x];head[x]:=tot;
end;
procedure insert(x,y,z:longint);
begin
ins(x,y,z);ins(y,x,);
end;
function bfs:boolean;
var i,x,y:longint;
begin
fillchar(h,sizeof(h),);
l:=;r:=;q[]:=s;h[s]:=;
while l<r do
begin
inc(l);
x:=q[l];
i:=head[x];
while i<> do
begin
y:=e[i].go;
if (e[i].v<>) and (h[y]=) then
begin
h[y]:=h[x]+;
inc(r);q[r]:=y;
end;
i:=e[i].next;
end;
end;
exit (h[t]<>);
end;
function dfs(x,f:longint):longint;
var i,y,used,tmp:longint;
begin
if x=t then exit(f);
used:=;
i:=cur[x];
while i<> do
begin
y:=e[i].go;
if (h[y]=h[x]+) and (e[i].v<>) then
begin
tmp:=dfs(y,min(e[i].v,f-used));
dec(e[i].v,tmp);if e[i].v<> then cur[x]:=i;
inc(e[i xor ].v,tmp);
inc(used,tmp);
if used=f then exit(f);
end;
i:=e[i].next;
end;
if used= then h[x]:=-;
exit(used);
end;
procedure dinic;
begin
while bfs do
begin
for i:= to n do cur[i]:=head[i];
inc(maxflow,dfs(s,inf));
end;
end;
procedure init;
begin
tot:=;
readln(n,m,s,t);
for i:= to m do
begin
readln(x,y,z);
insert(x,y,z);
end;
end;
procedure dfs(x:longint);
var i,y,z:longint;
begin
inc(ti);dfn[x]:=ti;low[x]:=ti;inc(top);sta[top]:=x;
i:=head[x];
while i<> do
begin
y:=e[i].go;
if e[i].v<> then
begin
if dfn[y]= then
begin
dfs(y);
low[x]:=min(low[x],low[y]);
end
else if scc[y]= then low[x]:=min(low[x],dfn[y]);
end;
i:=e[i].next;
end;
if low[x]=dfn[x] then
begin
inc(cnt);
while true do
begin
z:=sta[top];dec(top);
scc[z]:=cnt;
if z=x then break;
end;
end;
end;
procedure tarjan;
begin
ti:=;cnt:=;ti:=;
fillchar(dfn,sizeof(dfn),);
for i:= to n do if dfn[i]= then dfs(i);
end;
procedure main;
begin
dinic;
tarjan;
x:=scc[s];y:=scc[t];
for i:= to tot do
if (i and =) then
begin
if e[i].v<> then begin writeln('0 0');continue;end;
xx:=scc[e[i].from];yy:=scc[e[i].go];
if xx<>yy then write('') else write('');write(' ');
if (xx=x) and (yy=y) then write('') else write('');
writeln;
end;
end;
begin
assign(input,'input.txt');assign(output,'output.txt');
reset(input);rewrite(output);
init;
main;
close(input);close(output);
end.

AHOI2009最小割的更多相关文章

  1. P4126 [AHOI2009]最小割

    题目地址:P4126 [AHOI2009]最小割 最小割的可行边与必须边 首先求最大流,那么最小割的可行边与必须边都必须是满流. 可行边:在残量网络中不存在 \(x\) 到 \(y\) 的路径(强连通 ...

  2. 【BZOJ1797】[AHOI2009]最小割(网络流)

    [BZOJ1797][AHOI2009]最小割(网络流) 题面 BZOJ 洛谷 题解 最小割的判定问题,这里就当做记结论吧.(源自\(lun\)的课件) 我们先跑一遍最小割,求出残量网络.然后把所有还 ...

  3. P4126 [AHOI2009]最小割(网络流+tarjan)

    P4126 [AHOI2009]最小割 边$(x,y)$是可行流的条件: 1.满流:2.残量网络中$x,y$不连通 边$(x,y)$是必须流的条件: 1.满流:2.残量网络中$x,S$与$y,T$分别 ...

  4. 洛谷P4126 [AHOI2009]最小割

    题目:洛谷P4126 [AHOI2009]最小割 思路: 结论题 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t](否则s到t有通路,能继续 ...

  5. [AHOI2009]最小割

    题目 最小割的可行边和必须边 可行边\((u,v)\)需要满足以下两个条件 满流 残量网络中不存在\(u\)到\(v\)的路径 这个挺好理解的呀,如果存在还存在路径的话那么这条边就不会是瓶颈了 必须边 ...

  6. BZOJ1797:[AHOI2009]最小割(最小割)

    Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站 ...

  7. [AHOI2009]最小割 最小割可行边&必须边

    ~~~题面~~~ 题解: 做这题的时候才知道有最小割可行边和必须边这种东西..... 1,最小割可行边, 意思就是最小割中可能出现的边. 充要条件: 1,满流 2,在残余网络中找不到x ---> ...

  8. [BZOJ1797][AHOI2009]最小割Mincut

    bzoj luogu sol 一条边出现在最小割集中的必要条件和充分条件. 先跑出任意一个最小割,然后在残余网络上跑出\(scc\). 一条边\((u,v)\)在最小割集中的必要条件:\(bel[u] ...

  9. 洛谷$P4126\ [AHOI2009]$最小割 图论

    正解:网络流+$tarjan$ 解题报告: 传送门$QwQ$ $umm$最小割的判定问题$QwQ$,因为并不会做是看的题解才会的,所以也没什么推导过程直接放结论趴$QwQ$ 首先跑个最大流,然后有. ...

随机推荐

  1. 程序员面试题精选100题(16)-O(logn)求Fibonacci数列[算法]

    作者:何海涛 出处:http://zhedahht.blog.163.com/ 题目:定义Fibonacci数列如下: /  0                      n=0 f(n)=      ...

  2. dialog的传值

    A页面 等待B页面返回值的textBox:<asp:TextBox ID="TextBox1" runat="server"></asp:Te ...

  3. 计算序列中第k小的数

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046399.html 使用分治算法,首先选择随机选择轴值pivot,并使的序列中比pivot ...

  4. php的运行环境介绍

    php软件已下载在我的百度云:页面底部有地址,如有需要欢迎下载! 一:如何让php环境运行php代码? 直接使用php软件直接运行代码文件中的php代码 在B/S结构中让Apache使用php软件运行 ...

  5. trigger

    trigger() 方法触发被选元素的指定事件 <html><head><script type="text/javascript" src=&quo ...

  6. 关于Angular.js Routing 的学习笔记(实现单页应用)

    最近开始学习angular.js,发现angular.js确实很方便,也很强大.在看到 AngularJS Routing and Multiple Views 这一部分的时候,有点乱.现在通过记录一 ...

  7. PHP — 用PHP实现一个双向队列

    1.简介 deque,全名double-ended queue,是一种具有队列和栈的性质的数据结构.双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行.双向队列(双端队列)就像是一个队 ...

  8. django1.6之mysql配置

    # Database# https://docs.djangoproject.com/en/1.6/ref/settings/#databases setting 配置修改 INSTALLED_APP ...

  9. 【BZOJ】3309: DZY Loves Math 莫比乌斯反演优化

    3309: DZY Loves Math Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007) ...

  10. HIVE 的MAP/REDUCE

    对于 JOIN 操作: Map: 以 JOIN ON 条件中的列作为 Key,如果有多个列,则 Key 是这些列的组合 以 JOIN 之后所关心的列作为 Value,当有多个列时,Value 是这些列 ...