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

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

Sample Output

1 0
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

Solution

之前做过一道二分图残留网络上跑tarjan的题,
但当时为了应付作业并没有很深入的研究
为了这个题还重新去看了下最大流最小割定理
https://blog.csdn.net/w417950004/article/details/50538948
既然属于最小割集的边一定是满流的(为什么我之前学网络流的时候没看到这个性质……)
我们将原图tarjan缩点,剩下的一定只有满流边。(因为未满流的边(u,v)的正反向边和u点v点本来就可以缩一个点)
那么我们在缩点后的图上随手一割就是一个最小割(因为砍的都是满流边啊)
1、若u,v不属于同一个强连通分量,那么他们可以出现在某个最小割集中(因为两点如果在同一个强连通分量里面他们就已经作为不符合的被缩掉了)
2、若s和u属于同一个强连通分量,v和e属于同一个强连通分量,那么边(u,v)必须砍掉,否则可以继续增广

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N (5010)
using namespace std; struct node{int from,to,next,flow;}edge[N<<];
int n,m,s,e,u,v,l;
int head[N],num_edge;
int Dfn[N],vis[N],Low[N],Color[N];
int dfs_num,col_num;
int Depth[N],stack[N],top;
queue<int>q; void add(int u,int v,int l)
{
edge[++num_edge].to=v;
edge[num_edge].from=u;
edge[num_edge].next=head[u];
edge[num_edge].flow=l;
head[u]=num_edge;
} void Tarjan(int x)
{
Dfn[x]=Low[x]=++dfs_num;
vis[x]=true;
stack[++top]=x;
for (int i=head[x];i;i=edge[i].next)
if (edge[i].flow)
{
if (!Dfn[edge[i].to])
{
Tarjan(edge[i].to);
Low[x]=min(Low[x],Low[edge[i].to]);
}
else
if (vis[edge[i].to])
Low[x]=min(Low[x],Dfn[edge[i].to]);
}
if (Dfn[x]==Low[x])
{
vis[x]=false;
Color[x]=++col_num;
while (stack[top]!=x)
{
vis[stack[top]]=false;
Color[stack[top--]]=col_num;
}
top--;
}
} bool Bfs(int s,int e)
{
memset(Depth,,sizeof(Depth));
q.push(s);
Depth[s]=;
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=head[x]; i!=; i=edge[i].next)
if (!Depth[edge[i].to] && edge[i].flow>)
{
Depth[edge[i].to]=Depth[x]+;
q.push(edge[i].to);
}
}
return Depth[e];
} int Dfs(int x,int low)
{
int Min,f=;
if (x==e || low==)
return low;
for (int i=head[x]; i!=; i=edge[i].next)
if (edge[i].flow> && Depth[edge[i].to]==Depth[x]+ && (Min=Dfs(edge[i].to,min(low,edge[i].flow))))
{
edge[i].flow-=Min;
edge[((i-)^)+].flow+=Min;
low-=Min;
f+=Min;
if (low==) return f;
}
if (!f) Depth[x]=-;
return f;
} int Dinic(int s,int e)
{
int Ans=;
while (Bfs(s,e))
Ans+=Dfs(s,0x7fffffff);
return Ans;
} int main()
{
scanf("%d%d%d%d",&n,&m,&s,&e);
for (int i=;i<=m;++i)
{
scanf("%d%d%d",&u,&v,&l);
add(u,v,l); add(v,u,);
}
Dinic(s,e);
for (int i=;i<=n;++i)
if (!Dfn[i])
Tarjan(i);
for (int i=;i<=num_edge;i+=)
if (edge[i].flow)
printf("0 0\n");
else
{
if (Color[edge[i].from]!=Color[edge[i].to]) printf("1 ");
else printf("0 ");
if (Color[edge[i].from]==Color[s] && Color[edge[i].to]==Color[e]) printf("1\n");
else printf("0\n");
}
}

BZOJ1797:[AHOI2009]最小割(最小割)的更多相关文章

  1. scu - 3254 - Rain and Fgj(最小点权割)

    题意:N个点.M条边(2 <= N <= 1000 , 0 <= M <= 10^5),每一个点有个权值W(0 <= W <= 10^5),现要去除一些点(不能去掉 ...

  2. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  3. 3532: [Sdoi2014]Lis 最小字典序最小割

    3532: [Sdoi2014]Lis Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 865  Solved: 311[Submit][Status] ...

  4. 紫书 例题 11-2 UVa 1395(最大边减最小边最小的生成树)

    思路:枚举所有可能的情况. 枚举最小边, 然后不断加边, 直到联通后, 这个时候有一个生成树.这个时候,在目前这个最小边的情况可以不往后枚举了, 可以直接更新答案后break. 因为题目求最大边减最小 ...

  5. bzoj1797: [Ahoi2009]Mincut 最小割

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

  6. bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)

    1797: [Ahoi2009]Mincut 最小割 题目:传送门 题解: 感觉是一道肥肠好的题目. 第二问其实比第一问简单? 用残余网络跑强联通,流量大于0才访问. 那么如果两个点所属的联通分量分别 ...

  7. [BZOJ1797][AHOI2009]最小割Mincut

    bzoj luogu sol 一条边出现在最小割集中的必要条件和充分条件. 先跑出任意一个最小割,然后在残余网络上跑出\(scc\). 一条边\((u,v)\)在最小割集中的必要条件:\(bel[u] ...

  8. BZOJ1797 [Ahoi2009]Mincut 最小割 【最小割唯一性判定】

    题目 A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路 ...

  9. bzoj1797: [Ahoi2009]Mincut 最小割(网络流,缩点)

    传送门 首先肯定要跑一个最小割也就是最大流 然后我们把残量网络tarjan,用所有没有满流的边来缩点 一条边如果没有满流,那它就不可能被割了 一条边如果所属的两个强联通分量不同,它就可以被割 一条边如 ...

随机推荐

  1. 什么是web service (转)

    一.序言 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成分.但是不得不承认的是Web ...

  2. nrm的使用

    我们在开发过程中,经常会使用到 npm  install ,但是有时候npm是不稳定的,这就大大的降低了我们的开发效率.nrm正好解决了我们的这一痛点,他可以在不同的镜像之间切换,非常的方便. 一.n ...

  3. Effective C++ .14 智能指针的拷贝与deleter函数

    #include <iostream> #include <cstdlib> #include <memory> using namespace std; clas ...

  4. css3之背景属性之background-size

    一.相关属性: background-image: url(“./img/a.jpg”); //设置元素背景图片 background-repeat: repeat/no-repeat: //设置背景 ...

  5. avalon2简单数据绑定(自定义属性绑定)

    <!DOCTYPE html> <html> <head> <title>项目</title> <meta charset=" ...

  6. mongodb添加登陆验证

    mongodb添加登陆验证 转载地址 清空log,db目录 mongod --auth --logpath "D:\mongodb\log\log.log" --logappend ...

  7. 【Python】内置方法pop

    此时 a,b 指向的地址所存的内容均被更改

  8. Django后台注册

  9. SQL点点滴滴_常用函数

    该文章转载自http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 别人的总结,很详细. 以下所有例子均Studnet表为例 ...

  10. Linux的inode的理解 ZZ

    文件名 -> inode -> device block 转自:http://www.ruanyifeng.com/blog/2011/12/inode.htmlhttp://blog.s ...