【题目描述】

宇宙旅行总是出现一些意想不到的问题,这次小可可所驾驶的宇宙飞船所停的空间站发生了故障,这个宇宙空间站非常大,它由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. 2017最新xcode打包APP详细图文

    网上的xcode打包ipa教程大多太旧而且又不完整,所以整理了一个最新的完整详细的xcode打包APP的图文教程分享给小白到大神路上前进的你我. xcode打包IPA包之前先申请iOS证书,然后导入证 ...

  2. 《基于Node.js实现简易聊天室系列之详细设计》

    一个完整的项目基本分为三个部分:前端.后台和数据库.依照软件工程的理论知识,应该依次按照以下几个步骤:需求分析.概要设计.详细设计.编码.测试等.由于缺乏相关知识的储备,导致这个Demo系列的文章层次 ...

  3. js将时间戳转成格式化的时间

    function getLocalTime(nS){ return new Date(parseInt(nS) * 1000).toLocaleString().replace(/年|月/g, &qu ...

  4. CSS学习笔记10 相对定位,绝对定位与固定定位

    文档流中的元素的位置由元素在 (X)HTML 中的位置决定,这就是最原始的普通流,前面讲到的浮动CSS学习笔记08 浮动可以改变元素在文档流中的位置,除了这个我们还可以通过使用CSS的position ...

  5. linq 批量修改更新

    批量修改:var values = Context.Request["values"].JsonDeserialize<Dictionary<string, objec ...

  6. 不借助第三方网站四步实现手机网站转安卓APP

    今天本来是帮朋友查看是否在APP里可以点外链的一个测试,做着做来感觉了,就把这个测试优化了一下.好了我们来进入正题. 工具:Android Studio 第一步:新建项目 第二步:拖入控件(WebVi ...

  7. 在两个ASP.NET页面之间传递变量【转】

    ASP.NET提供了事件驱动编程模型,使开发者简化了应用程序的总体设计,但是这个也造成了它固有的一些问题,例如,在传统的ASP里,我们可以通过使用POST方法很容易地实现页面间传递变量,同样的事情,在 ...

  8. oracle linux 7.3 下用dtrace 跟踪 mysql-community-server-5.6.20

    第一部分:oracle linux 7.3 dtrace 安装: http://public-yum.oracle.com/   内核升极到 [root@server1 SPECS]# uname - ...

  9. iOS动画学习-CALayer

    iOS中有很多方法可以实现动画,我们可以用CAKeyframeAnimation, CABasicAnimation,CASpringAnimation(iOS9.0中添加的,实现弹簧的效果),也可以 ...

  10. classloader加载的双亲委托模式

    要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用 的.我们知道,java程序可以动态加载类定义,而这个动 ...