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 ...
随机推荐
- 转载:《TypeScript 中文入门教程》 2、枚举
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 由于第一章节是我翻译的,而且与他的版本不一致,导致第一章节有枚举这部分,而他的第二章节 ...
- 使用python发送和接收邮件
关于电子邮件 大学之前,基本不用邮箱,所以基本感觉不到它的存在,也不知道有什么用:然而大学之后,随着认识的人越来越多,知识越来越广泛,邮箱已然成为很重要的通讯工具,大学一些课程作业需要有邮箱发给老师, ...
- centos svn服务器搭建
1.安装svnyum install subversion查看安装目录rpm -ql subversion 查看yum安装subversion的位置 2.创建仓库创建版本库目录mkdir -p /va ...
- 妈妈再也不用担心我找不到spring源码了!
获取spring源码: http://repo.springsource.org/libs-release-local/ http://repo.springsource.org/libs-relea ...
- input标签内容改变的触发事件
---恢复内容开始--- 1. onchange事件与onpropertychange事件的区别: onchange事件在内容改变(两次内容有可能相等)且失去焦点时触发:onpropertychang ...
- 1-1 console的用法
console里面具体提供了哪些方法可以供我们平时调试时使用. 目前控制台方法和属性有: ["$$", "$x", "dir", " ...
- jquery编写插件的方法
版权声明:作者原创,转载请注明出处! 编写插件的两种方式: 1.类级别开发插件(1%) 2.对象级别开发(99%) 类级别的静态开发就是给jquery添加静态方法,三种方式 1.添加新的全局函数 2 ...
- Android 手机卫士--确认密码对话框编写
本文接着实现“确认密码”功能,也即是用户以前设置过密码,现在只需要输入确认密码 本文地址:http://www.cnblogs.com/wuyudong/p/5940718.html,转载请注明出处. ...
- 适配ios10(iTunes找不到构建版本)
前两天上架App遇到一个比较神奇的问题,打包好的项目使用Application Loader上传成功,但是在iTunes里面却找不到构建版本,App的活动页面也没有相应的版本. 之前了解IOS10对用 ...
- 关于watir-webdriver中文乱码问题
require 'watir-webdriver' require 'iconv' cov = Iconv.new( 'gbk', 'utf-8') b = Watir::Browser.new b. ...