BZOJ 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2076 Solved: 885
[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
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
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
分析:
我们发现最小割就是把从S到T的路径全部切断,也就是说如果去掉了最小割中的某一条边(u,v),我们无法再找到一条可以替代它的路径,因为最小割中的变一定是满流的,所以如果两个点在一个强连通分量中,我们就可以找到另一条从u到v的路径...所以只要tarjan缩点,满流边的两个点不在同一个强连通分量中就可以成为最小割的可行边...
因为如果在残留网络中可以从S到u,那么一定存在反向边可以从u到S,所以S和u一定在同一个强连通分量中...所以也可以判断SuvT是否在同一强连通分量中来找必须边...
BUT!!!!!NOTICE!!!!!
如果要使用tarjan的话说,需要注意的是不存在容量为0的边,如果存在,容量为0的边是不可能被算为必须边的,在求最小割必须边的时候是对的,但是如果是网络流的必须边就是错误的!!!!!!
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
//by NeighThorn
#define inf 0x3f3f3f3f
#define M 60000*3
using namespace std;
//大鹏一日同风起,扶摇直上九万里 const int maxn=+,maxm=*+; int n,m,S,T,cnt,id[maxm],hd[maxn],to[maxm],fl[maxm],nxt[maxm],vis[maxn],pos[maxn],flag[maxm],ans1[maxm],ans2[maxm]; int C,tim,tail,mp[maxn],dfn[maxn],low[maxn],stk[maxn],instk[maxn]; inline void add(int s,int x,int y,int l){
fl[cnt]=s;id[cnt]=l;to[cnt]=y;nxt[cnt]=hd[x];flag[cnt]=;hd[x]=cnt++;
fl[cnt]=;id[cnt]=M;to[cnt]=x;nxt[cnt]=hd[y];flag[cnt]=;hd[y]=cnt++;
} inline bool bfs(void){
memset(pos,-,sizeof(pos));
int head=,tail=,q[maxn];
q[]=S,pos[S]=;
while(head<=tail){
int top=q[head++];
for(int i=hd[top];i!=-;i=nxt[i])
if(pos[to[i]]==-&&fl[i])
pos[to[i]]=pos[top]+,q[++tail]=to[i];
}
return pos[T]!=-;
} inline int find(int v,int f){
if(v==T)
return f;
int res=,t;
for(int i=hd[v];i!=-&&f>res;i=nxt[i])
if(pos[to[i]]==pos[v]+&&fl[i])
t=find(to[i],min(f-res,fl[i])),fl[i]-=t,fl[i^]+=t,res+=t;
if(!res)
pos[v]=-;
return res;
} inline void dinic(void){
while(bfs())
while(find(S,inf));
} inline void tarjan(int root){
dfn[root]=low[root]=++tim;stk[++tail]=root;instk[root]=;
for(int i=hd[root];i!=-;i=nxt[i])
if(fl[i]){
if(dfn[to[i]]==)
tarjan(to[i]),low[root]=min(low[root],low[to[i]]);
else if(instk[to[i]])
low[root]=min(low[root],dfn[to[i]]);
}
if(low[root]==dfn[root]){
int tmp;C++;
do{
tmp=stk[tail--];instk[tmp]=;mp[tmp]=C;
}while(tmp!=root);
}
} signed main(void){
memset(hd,-,sizeof(hd));
memset(vis,,sizeof(vis));
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(instk,,sizeof(instk));
scanf("%d%d%d%d",&n,&m,&S,&T);
for(int i=,s,x,y;i<=m;i++)
scanf("%d%d%d",&x,&y,&s),add(s,x,y,i);
dinic();C=tim=tail=;
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=;i<=n;i++)
for(int j=hd[i];j!=-;j=nxt[j])
if(flag[j]&&fl[j]==)
ans1[j]=(mp[i]==mp[to[j]]?:),ans2[j]=((mp[i]==mp[S]&&mp[to[j]]==mp[T])?:);
for(int i=;i<cnt;i+=)
printf("%d %d\n",ans1[i],ans2[i]);
return ;
}//Cap ou pas cap. Cap.
By NeighThorn
BZOJ 1797: [Ahoi2009]Mincut 最小割的更多相关文章
- BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )
先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...
- ●BZOJ 1797 [Ahoi2009]Mincut 最小割
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1797 题解: 详细的讲解去看http://hzwer.com/3217.html首先跑一个最 ...
- bzoj 1797: [Ahoi2009]Mincut 最小割【tarjan+最小割】
先跑一遍最大流,然后对残量网络(即所有没有满流的边)进行tarjan缩点. 能成为最小割的边一定满流:因为最小割不可能割一半的边: 连接s.t所在联通块的满流边一定在最小割里:如果不割掉这条边的话,就 ...
- bzoj 1797: [Ahoi2009]Mincut 最小割 (网络流)
太神了直接看了hzwer的题解,有个新认识,一条路径上满流的一定是这条路径上所有边的最小值. type arr=record toward,next,cap,from:longint; end; co ...
- 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...
- bzoj1797: [Ahoi2009]Mincut 最小割
最大流+tarjan.然后因为原来那样写如果图不连通的话就会出错,WA了很久. jcvb: 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t] ...
- bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)
1797: [Ahoi2009]Mincut 最小割 题目:传送门 题解: 感觉是一道肥肠好的题目. 第二问其实比第一问简单? 用残余网络跑强联通,流量大于0才访问. 那么如果两个点所属的联通分量分别 ...
- BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan
BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...
- 【bzoj1797】 Ahoi2009—Mincut 最小割
http://www.lydsy.com/JudgeOnline/problem.php?id=1797 (题目链接) 题意 求一条边是否可能在一个最小割集中,以及这条边是否一定在最小割集中. Sol ...
随机推荐
- Hibernate-chapter one
======什么是Hibernate???====== Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的 ...
- UDS(ISO14229-2006) 汉译(No.6 应用层服务)
6.1总览 应用层服务通常被当作诊断服务.应用层服务用于在基于客户端-服务器的系统(Client-Server base System)中执行一些功能,例如针对车载服务器(ECU)的检测.检查.监控和 ...
- 微软Microsoft开源历程与相关资源
2001 Open source is bad for business, saysMicrosoft Linux is a cancer 2005 Enterprise Library 1.0 re ...
- 一个强大的jquery分页插件
点击这里查看效果 这个分页插件使用方便,引用keleyidivpager.js和keleyidivpager.css文件,然后在htm(或者php,aspx,jsp等)页面中对分页总数,参数名,前缀后 ...
- nth-child和:nth-of-type的区别
:nth-of-type为什么要叫:nth-of-type?因为它是以"type"来区分的.也就是说:ele:nth-of-type(n)是指父元素下第n个ele元素, 而ele: ...
- CSS :first-child 选择器 和 HTML DOM firstChild 属性
CSS 选择器参考手册 实例 选择属于其父元素的首个子元素的每个 <p> 元素,并为其设置样式: p:first-child { background-color:yellow; } 亲自 ...
- 最大似然判别法和Bayes公式判别法
最大似然判别法 Bayes公式判别法
- SharePoint 2013 对二进制大型对象(BLOB)进行爬网
本文是参考MSDN文档做的示例,SharePoint 2013搜索二进制对象(BLOB),通过外部内容类型的方式将外部数据与SharePoint相关联,修改BCD模型,使SharePoint能够爬网外 ...
- Tableview中Dynamic Prototypes动态表的使用
Tableview时IOS中应用非常广泛的控件,当需要动态的添加多条不同的数据时,需要用动态表来实现,下面给出一个小例子,适用于不确定Section的数目,并且每个Section中的行数也不同的情况, ...
- iOS开发之聊天模块--内容保存逻辑实现
需求详解: 在实际开发中,有可能是在后期优化的时候,会有这么需要优化的需求:聊天输入框保存之前输入的文本,提高用户的良好体验. 在聊天模块中,用户可能会在输入框输入若干字符,但是没有点击发送就点击退出 ...