最小截断[AHOI2009]
【题目描述】
宇宙旅行总是出现一些意想不到的问题,这次小可可所驾驶的宇宙飞船所停的空间站发生了故障,这个宇宙空间站非常大,它由N个子站组成,子站之间有M条单向通道,假设其中第i(1<=i<=M)条单向通道连接了xi,yi两个中转站,那么xi子站可以通过这个通道到达yi子站,如果截断这条通道,需要代价ci。现在为了将故障的代价控制到最小,小可可必须想出一个截断方案,使a站不能到达b子站,并且截断的代价之和最小。我们称之为最小截断,小可可很快解决了这个故障,但是爱思考的小可可并不局限于此,为了今后更方便的解决同类故障,他考虑对每条单向通道:
1,是否存在一个最小代价路径截断方案,其中该通道被切断?
2,是否对任何一个最小代价路径切断方案,都有该通道被切断?
聪明的你能帮小可可解决他的疑问吗?
【输入格式】
第一行有4个整数,依次为N,M,a和b;
第二行到第(m+1)行每行3个正整数x,y,c表示x子站到y子站之间有单向通道相连,单向通道的起点是x终点是y,切断它的代价是c(1<=c<=10000);
两个子站之间可能有多条通道直接连接。
【输出格式】
对每一个单向通道,按输入的顺序,依次输出一行包含两个非0即1的整数,分别表示对问题一和问题二的回答(其中1表示是,0表示否)。每行两个整数之间用一个空格分隔开。
【样例输入】
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
【样例输出】
1 0
1 0
0 0
1 0
0 0
1 0
1 0
【提示】
100%的数据中,N<=4000,M<=60000
70%的数据中,N<=1000,M<=40000
40%的数据中,N<=200,M<=2000
【题解】
血帆海盗的进阶版,先贴结论XDDD:
最小割的必须边
一定在最小割中的边、扩大容量后能增大最大流的边, ① 满流;② 残余网络中S能到入点、出点能到T。 从S开始DFS、T开始反向DFS,标记到达的点,然后枚举满流边即可。
最小割的可行边
被某一种最小割的方案包含的边, ① 满流;② 删掉之后在残余网络中找不到u到v的路径。 在残余网络中tarjan求SCC,(u,v)两点在同一SCC中说明残余网络中存在u到v路径。
但是在这道题里求必须边好像不能用dfs,上面那个结论已经忘了是从哪里看的了= =,必须边的起点与S在同一个强联通分量里,终点与T在同一个强联通分量里。知道了结论之后就可以放心地跑了。
写一点理解:残余网络中不能形成强连通分量的只有满流边(或许还有没用到的边?但是那不会被统计答案),所以残余网络缩成DAG的每个s-t割都是原图中的一个最小割,这是可行性。而u、v分别和s、t同处一个强联通分量的边一旦边权增加就会产生增广路径,这恰好符合必须边的定义。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
using namespace std;
queue<int> q;
stack<int> s;
const int sj=;
const int sm=;
int n,m,si,t,a1,a2,a3,e,h[sj],c[sj],dep[sj],dfn[sj],low[sj];
bool r[sj];
struct B
{
int ne,v,w,u;
}b[sm<<];
inline int read()
{
int jg=,jk=getchar()-'';
while(jk<||jk>) jk=getchar()-'';
while(jk>=&&jk<=) jg*=,jg+=jk,jk=getchar()-'';
return jg;
}
void add(int x,int y,int z)
{
b[e].u=x,b[e].v=y,b[e].w=z,b[e].ne=h[x],h[x]=e++;
b[e].u=y,b[e].v=x,b[e].w=,b[e].ne=h[y],h[y]=e++;
}
bool bfs(int x)
{
memset(dep,,sizeof(dep));
while(!q.empty()) q.pop();
dep[x]=,q.push(x);
while(!q.empty())
{
x=q.front(),q.pop();
for(int i=h[x];i!=-;i=b[i].ne)
if(!dep[b[i].v]&&b[i].w)
{
dep[b[i].v]=dep[x]+;
if(b[i].v==t) return ;
q.push(b[i].v);
}
}
return ;
}
int dfs(int x,int f)
{
if(x==t) return f;
int ret=,d;
for(int i=h[x];i!=-;i=b[i].ne)
if(dep[b[i].v]==dep[x]+&&b[i].w)
{
d=dfs(b[i].v,min(f,b[i].w));
ret+=d,f-=d;
b[i].w-=d,b[i^].w+=d;
if(!f) break;
}
if(!ret) dep[x]=-;
return ret;
}
void bj(int &x,int y)
{
x=x<y?x:y;
}
void tarjan(int x)
{
dfn[x]=low[x]=++a1,r[x]=,s.push(x);
for(int i=h[x];i!=-;i=b[i].ne)
{
if(!b[i].w) continue;
if(!dfn[b[i].v]) tarjan(b[i].v),bj(low[x],low[b[i].v]);
else if(r[b[i].v]) bj(low[x],dfn[b[i].v]);
}
if(low[x]==dfn[x])
{
a2++;
do
{
a3=s.top(),s.pop();
r[a3]=,c[a3]=a2;
}while(a3!=x);
}
}
int main()
{
memset(h,-,sizeof(h));
n=read(),m=read(),si=read(),t=read();
for(int i=;i<=m;i++)
{
a1=read(),a2=read(),a3=read();
add(a1,a2,a3);
}
while(bfs(si)) dfs(si,0x7fffffff);
a1=a2=a3=;
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<e;i+=)
{
if(b[i].w) printf("0 0\n");
else
{
if(c[b[i].u]!=c[b[i].v])
{
if(c[b[i].v]==c[t]&&c[b[i].u]==c[si]) printf("1 1\n");
else printf("1 0\n");
}
else printf("0 0\n");
}
}
return ;
}
mincut
最小截断[AHOI2009]的更多相关文章
- gensim中word2vec
from gensim.models import Word2Vec Word2Vec(self, sentences=None, size=100, alpha=0.025, window=5, m ...
- 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] ...
- AHOI2009最小割
1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1072 Solved: 446[Submit] ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )
先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...
- BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan
BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...
- P4126 [AHOI2009]最小割
题目地址:P4126 [AHOI2009]最小割 最小割的可行边与必须边 首先求最大流,那么最小割的可行边与必须边都必须是满流. 可行边:在残量网络中不存在 \(x\) 到 \(y\) 的路径(强连通 ...
- 【BZOJ1797】[AHOI2009]最小割(网络流)
[BZOJ1797][AHOI2009]最小割(网络流) 题面 BZOJ 洛谷 题解 最小割的判定问题,这里就当做记结论吧.(源自\(lun\)的课件) 我们先跑一遍最小割,求出残量网络.然后把所有还 ...
- 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...
随机推荐
- PHP 上传文件大小限制
配置php.ini文件 (以上传500M以下大小的文件为例) 查找以下选项并修改-> file_uploads = On ;打开文件上传选项 upload_max_filesize = 500M ...
- 学习php语法--数据库扩展(总结篇)
前 言 php php中的数据库扩展mysql语法--本篇学习都是通过使用数字天堂的HBuider开发环境,连接mysql数据.介绍php连接mysql数据库的代码与函数. 本篇学习主要有两 ...
- 无法为具有固定名称“MySql.Data.MySqlClient”的 ADO.NET 提供程序加载在应用程序配置文件中注册的实体框架提供程序类型“MySql.Data.MySqlClient.MySqlProviderServices,MySql.Data.Entity.EF6”
"System.InvalidOperationException"类型的未经处理的异常在 mscorlib.dll 中发生 其他信息: 无法为具有固定名称"MySql. ...
- 并发编程(四):ThreadLocal从源码分析总结到内存泄漏
一.目录 1.ThreadLocal是什么?有什么用? 2.ThreadLocal源码简要总结? 3.ThreadLocal为什么会导致内存泄漏? 二.ThreadLoc ...
- 利用wamp配置虚拟主机
第一步:打开wamp--Apache--httpd.conf找到# Virtual hosts 一行,把其下面的一行中的#去掉.
- Mathematica 10 Mac 设置默认工作目录
用SetDirectory命令设置
- 钉钉企业应用C#开发笔记之一(免登)
关于钉钉 钉钉是阿里推出的企业移动OA平台,本身提供了丰富的通用应用,同时其强大的后台API接入能力让企业接入自主开发的应用成为可能,可以让开发者实现几乎任何需要的功能. 近期因为工作需要研究了一下钉 ...
- Chrome浏览器扩展开发系列之十六:扩展中可用的Chrome浏览器API
除了Chrome浏览器支持的chrome.* API之外,Chrome浏览器扩展还可以使用Chrome浏览器为Web页面或Chrome app提供的APIs.对于Chrome浏览器2支持的API,还可 ...
- TCP错误恢复特性之一TCP重传
TCP的错误恢复特性是我们用来定位.诊断并最终修复网络高延迟的最好工具. 常见的TCP错误恢复特性有:TCP重传.TCP重复确认和快速重传 1. TCP重传: 重传数据包是TCP最基本的错误恢复特性之 ...
- java开发必读 书单
希望读的书单 重构 改善既有代码的设计 设计模式 可复用面向对象软件的基础 高性能MySQL第3版 Effective Java第1版 Effective Java第2版 Java核心技术I-基础知识 ...