BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan
BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan
Description
A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路。设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路,需要代价ci。现在B国想找出一个路径切断方案,使中转站s不能到达中转站t,并且切断路径的代价之和最小。 小可可一眼就看出,这是一个求最小割的问题。但爱思考的小可可并不局限于此。现在他对每条单向道路提出两个问题: 问题一:是否存在一个最小代价路径切断方案,其中该道路被切断? 问题二:是否对任何一个最小代价路径切断方案,都有该道路被切断? 现在请你回答这两个问题。
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
1 0
0 0
1 0
0 0
1 0
1 0
首先求一遍最小割,然后在残量网络缩点。显然有S,T不在同一强连通分量中。
考虑边(u,v) ,如果u和v在同一scc中,那么割去这条边后仍有通路,因此它不会出现在任何一边的割集当中。
如果S和u在同一scc并且v和T在同一scc,那么假设在这条边上多加一些流量,那么从S到T则又可以增广,因此它一定会被割掉。
如果这条边没有满流,它同样不会被割掉。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 5000
#define M 120050
#define inf 100000000
#define mem(x) memset(x,0,sizeof(x));
int head[N],to[M],nxt[M],flow[M],n,m,cnt=1;
int dep[N],Q[N],l,r,S,T;
int St[N],top,ins[N],bl[N],scc,tot,dfn[N],low[N];
inline void add(int u,int v,int f){
to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;flow[cnt]=f;
}
bool bfs(){
l=r=0;
mem(dep);
Q[r++]=S;dep[S]=1;
while(l<r){
int x=Q[l++];
for(int i=head[x];i;i=nxt[i]){
if(!dep[to[i]]&&flow[i]){
dep[to[i]]=dep[x]+1;
if(to[i]==T)return 1;
Q[r++]=to[i];
}
}
}return 0;
}
int dfs(int x,int mf){
if(x==T)return mf;
int nf=0;
for(int i=head[x];i;i=nxt[i]){
if(dep[to[i]]==dep[x]+1&&flow[i]){
int tmp=dfs(to[i],min(mf-nf,flow[i]));
nf+=tmp;
flow[i]-=tmp;
flow[i^1]+=tmp;
if(nf==mf)break;
}
}
dep[x]=0;return nf;
}
void dinic(){
int ans=0,f=0;
while(bfs()){
while(f=dfs(S,inf)){
ans+=f;
}
}
}
void tarjan(int x){
dfn[x]=low[x]=++tot;
St[top++]=x;ins[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(flow[i]==0)continue;
if(!dfn[to[i]]){
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}else if(!bl[to[i]]){
low[x]=min(low[x],dfn[to[i]]);
}
}
if(low[x]==dfn[x]){
int t=St[--top];ins[t]=0;
bl[t]=++scc;
while(t^x){
t=St[--top];ins[t]=0;
bl[t]=scc;
}
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&S,&T);
int x,y,z;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,0);
}
dinic();
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
for(int i=1;i<=m;i++){
if(flow[i<<1]){
printf("0 0\n");continue;
}
int g=to[i<<1|1],h=to[i<<1];
printf("%d %d\n",bl[g]!=bl[h],bl[g]==bl[S]&&bl[h]==bl[T]);
/*if(bl[g]!=bl[h])printf("1");
else printf("0");
if(bl[g]==bl[S]&&bl[h]==bl[T])printf(" 1\n");
else printf(" 0\n");*/
}
}
BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan的更多相关文章
- [bzoj4519][Cqoi2016]不同的最小割_网络流_最小割_最小割树
不同的最小割 bzoj-4519 Cqoi-2016 题目大意:题目链接. 注释:略. 想法: 我们发现这和最小割那题比较像. 我们依然通过那个题说的办法一样,构建最小割树即可. 接下来就是随便怎么处 ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2076 Solved: 885[Submit] ...
- bzoj1797: [Ahoi2009]Mincut 最小割
最大流+tarjan.然后因为原来那样写如果图不连通的话就会出错,WA了很久. jcvb: 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t] ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )
先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...
- 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...
- bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)
1797: [Ahoi2009]Mincut 最小割 题目:传送门 题解: 感觉是一道肥肠好的题目. 第二问其实比第一问简单? 用残余网络跑强联通,流量大于0才访问. 那么如果两个点所属的联通分量分别 ...
- BZOJ1797 [Ahoi2009]Mincut 最小割 【最小割唯一性判定】
题目 A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路 ...
- bzoj 1797: [Ahoi2009]Mincut 最小割【tarjan+最小割】
先跑一遍最大流,然后对残量网络(即所有没有满流的边)进行tarjan缩点. 能成为最小割的边一定满流:因为最小割不可能割一半的边: 连接s.t所在联通块的满流边一定在最小割里:如果不割掉这条边的话,就 ...
- bzoj1797: [Ahoi2009]Mincut 最小割(网络流,缩点)
传送门 首先肯定要跑一个最小割也就是最大流 然后我们把残量网络tarjan,用所有没有满流的边来缩点 一条边如果没有满流,那它就不可能被割了 一条边如果所属的两个强联通分量不同,它就可以被割 一条边如 ...
随机推荐
- Java 必看的 Spring 知识汇总!有比这更全的算我输!
往 期 精 彩 推 荐 [1]Java Web技术经验总结 [2]15个顶级Java多线程面试题及答案,快来看看吧 [3]面试官最喜欢问的十道java面试题 [4]从零讲JAVA ,给你一条清晰 ...
- java并发容器(Map、List、BlockingQueue)
转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collectio ...
- AngularJs 学习笔记(三)依赖注入
一个对象可以通过三种方式来获取对依赖对象的控制权: 1.在内部创建依赖的对象 2.通过全局变量引用这个依赖对象 3.通过参数进行传递(在这里是通过函数参数) AngularJs通过$injector注 ...
- iOS Swift开发的一些坑
0.人难招,特别是对于没钱的小团队,大多数的iOS开发者没有Swift经验,有经验的也并不是很深入 0.1.语言unwrap坑,虽然有自动修正提示,但感觉代码过程不流畅. 1.Realm的缺憾: 最近 ...
- JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable
JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...
- 通过Django Channels设计聊天机器人WEB框架
这两个月都在忙着设计针对银联客服业务的智能聊天机器人,上一周已经交完设计报告,这一周还和部门同事一起分享了系统设计及运行效果.因为时间的关系,系统原型我使用了Flask+jQuery的组合,感觉用以原 ...
- Java容器:Map
1. Map概述 1.1. Map类的继承关系 1.2. 几个Map接口类概念 1.3. Map类的通用方法 2. HashMap 2.1. 构造函数 2.2. 数据结构 2.3. 存储实现 3. H ...
- python之文件操作(基础)
文件操作作为python基础中的重点,必须要掌握. 1.默认我们在本地电脑E盘新建wp.txt文件进行测试,文件内容如下设置. 2.进行代码编写: f=open("E://wp.txt&qu ...
- Java面向对象(二、继承)
Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法 ...
- Python:怎样用线程将任务并行化?
如果待处理任务满足: 可拆分,即任务可以被拆分为多个子任务,或任务是多个相同的任务的集合: 任务不是CPU密集型的,如任务涉及到较多IO操作(如文件读取和网络数据处理) 则使用多线程将任务并行运行,能 ...