【题目描述】

宇宙旅行总是出现一些意想不到的问题,这次小可可所驾驶的宇宙飞船所停的空间站发生了故障,这个宇宙空间站非常大,它由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]的更多相关文章

  1. gensim中word2vec

    from gensim.models import Word2Vec Word2Vec(self, sentences=None, size=100, alpha=0.025, window=5, m ...

  2. BZOJ 1797: [Ahoi2009]Mincut 最小割

    1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2076  Solved: 885[Submit] ...

  3. bzoj1797: [Ahoi2009]Mincut 最小割

    最大流+tarjan.然后因为原来那样写如果图不连通的话就会出错,WA了很久. jcvb: 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t] ...

  4. AHOI2009最小割

    1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1072  Solved: 446[Submit] ...

  5. BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )

    先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...

  6. BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan

    BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...

  7. P4126 [AHOI2009]最小割

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

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

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

  9. 1797: [Ahoi2009]Mincut 最小割

    1797: [Ahoi2009]Mincut 最小割 链接 分析: 题意为:问一条边是否可能存在于最小割中,是否一定存在于最小割中. 首先最小割的边一定是满流的边.且这条边点两个端点u.v中,至少一个 ...

随机推荐

  1. Linq之关键字基本查询

    子句 说明 from 指定数据源和范围变量(类似于迭代变量). where 根据一个或多个由逻辑"与"和逻辑"或"运算符(&& 或 ||)分隔的 ...

  2. AospExtended K3 Note最新官方版 Android7.1.2 极速 省电 流畅 Galaxy XIAOMI Moto Lenovo Coolpad 均支持

    AospExtended 最新官方版 Android7.1.2 极速 省电 流畅 Galaxy  XIAOMI Moto  Lenovo  Coolpad  均支持 之前用过1629开发版等,体验了很 ...

  3. 【翻译】旧技术成就新勒索软件,Petya添加蠕虫特性

    原文链接:https://blogs.technet.microsoft.com/mmpc/2017/06/27/new-ransomware-old-techniques-petya-adds-wo ...

  4. 【Android Developers Training】 22. 与其他fragment通信

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  5. SequoiaDB版本在线升级介绍说明

    1.前言 在SequoiaDB数据库发展过程中,基本保持每半年对外发行一个正式的Release版本.并且每个新发布的Release版本相对老版本而言,性能方面都有很大的提高,并且数据库也会在新版本中加 ...

  6. Ext TabPanel tabbar添加按钮

    tabPanel tabbar添加按钮 this.tabPanel = Ext.create('Ext.tab.Panel', { tabBar:{ items:[{ //组件靠右 xtype: 't ...

  7. Redis事务原理分析

    Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...

  8. 前端解读Webview

    作为盛行已久的开发方式,Hybrid的相关介绍已经是相当普遍了.不过看到博客园里基本上都是从android或者ios的角度来讲解的,对于h5的前端来说看起来只能是一直半解.感觉有必要从前端的角度来理解 ...

  9. (转载)oracle 在一个存储过程中调用另一个返回游标的存储过程

    原文链接:http://www.jb51.net/article/20160.htm 实际项目当中经常需要在一个存储过程中调用另一个存储过程返回的游标,本文列举了两种情况讲述具体的操作方法. 第一种情 ...

  10. 【.net 深呼吸】自己动手来写应用程序设置类

    在开始装逼之前,老周先说明一件事.有人说老周写的东西太简单了,能不能写点复杂点.这问题就来了,要写什么东西才叫“复杂”?最重要的是,写得太复杂了,一方面很多朋友看不懂,另一方面,连老周自己也不知道怎么 ...