[BZOJ]1797: [Ahoi2009]Mincut 最小割 网络流+强连通
来源:互联网 发布:印度 网络空间 编辑:程序博客网 时间:2024/06/05 17:13
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
题解:
显然,只有满流边有可能被割。对于原图先跑一遍网络流,之后再对残量网络跑一遍强连通(此时的边包括反向弧)。对于每一条满流边,第一个问当belong[u]!=belong[v]时,输出1。(belong[i]为i所属的连通分量)因为u->v的这条边是满流的,它的反向边v->u显然不是满流,若u,v属于同一个连通分量,则u->v还存在路径,割掉此边无意义。第二个问,当belong[st]==belong[u]且belong[v]==belong[ed]时输出1。显然,缩点之后的图的最小割就是原图的最小割(割联通分量中的边无意义),所以满足以上条件,此边一定在割集中。
代码:
#include<cstdio>#include<cstring>#include<queue>#include<iostream>#include<algorithm>using namespace std;const int maxn=8000;int h[maxn];struct Edge{int x,y,d,next;}e[160010];int N,M,st,ed;int last[maxn],len=1;void ins(int x,int y,int d){ int t=++len; e[t].x=x;e[t].y=y;e[t].d=d; e[t].next=last[x];last[x]=t;}void addedge(int x,int y,int d){ins(x,y,d);ins(y,x,0);}queue<int>q;bool bfs(){ memset(h,0,sizeof(h));h[st]=1; q.push(st); while(!q.empty()) { int x=q.front();q.pop(); for(int i=last[x];i;i=e[i].next) if(h[e[i].y]==0&&e[i].d)q.push(e[i].y),h[e[i].y]=h[x]+1; } return h[ed];}int dfs1(int x,int f){ if(x==ed)return f; int s=0,t; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(h[y]==h[x]+1&&e[i].d&&s<f) { t=dfs1(y,min(f-s,e[i].d)); s+=t;e[i^1].d+=t;e[i].d-=t; } } if(s==0)h[x]=0; return s;}int low[maxn],dfn[maxn],id=0,sta[maxn],top=0,belong[maxn],cnt=0;bool in[maxn];void dfs2(int x){ sta[++top]=x;in[x]=true; low[x]=dfn[x]=++id; for(int i=last[x];i;i=e[i].next) if(e[i].d) { int y=e[i].y; if(dfn[y]==-1)dfs2(y),low[x]=min(low[x],low[y]); else if(in[y])low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { cnt++; int i; do { i=sta[top--]; belong[i]=cnt; in[i]=false; }while(i!=x); }}int main(){ memset(dfn,-1,sizeof(dfn)); scanf("%d%d%d%d",&N,&M,&st,&ed); for(int i=1;i<=M;i++) { int v,u,c; scanf("%d%d%d",&v,&u,&c); addedge(v,u,c); } int ans=0; while(bfs())ans+=dfs1(st,1<<30); for(int i=1;i<=N;i++) if(dfn[i]==-1)dfs2(i); for(int i=2;i<=len;i+=2) if(e[i].d)puts("0 0"); else { if(belong[e[i].x]!=belong[e[i].y])printf("1 "); else printf("0 "); if(belong[e[i].x]==belong[st]&&belong[e[i].y]==belong[ed])puts("1"); else puts("0"); }}
- [BZOJ]1797: [Ahoi2009]Mincut 最小割 网络流+强连通
- bzoj1797 [Ahoi2009]Mincut 最小割 网络流+强连通分量
- [BZOJ1797][AHOI2009][最大流][强连通分量]Mincut最小割
- [BZOJ1797][Ahoi2009]Mincut 最小割 && 最小割+强连通
- bzoj 1797: [Ahoi2009]Mincut 最小割
- 【BZOJ 1797】 [Ahoi2009]Mincut 最小割
- BZOJ 1797 [Ahoi2009]Mincut 最小割
- bzoj 1797: [Ahoi2009]Mincut 最小割
- bzoj 1797: [Ahoi2009]Mincut 最小割 (最小割+tarjan)
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 1797: [Ahoi2009]Mincut 最小割
- 【 bzoj 1797 】[Ahoi2009]Mincut 最小割 - 经典题
- [Ahoi2009]Mincut 最小割
- 【bzoj 1797】 [Ahoi2009]Mincut 最小割(最大流+Tarjan缩点)
- 1797: [Ahoi2009]Mincut 最小割(from hzwer)
- [最小割唯一性 Tarjan] BZOJ 1797 [Ahoi2009]Mincut 最小割
- 【R和Python对比】数据整形
- Openpose安装
- echarts3.0在加载省市地图——小白日记
- 【“盛大游戏杯”第15届上海大学程序设计联赛 M】【线段树 时间维度线段树 前缀和标记 离线询问】风力观测 历史最大值
- 用线性判别分析 LDA 降维
- [BZOJ]1797: [Ahoi2009]Mincut 最小割 网络流+强连通
- linux常用的命令
- 日期 2017-07-12 学习记录
- 关于STM32中RTC的校准方法
- 我说理解的Rxjava(1)
- 刷新iframe页面$('#iframe').attr('src', $('#iframe').attr('src'));
- WorkFlow工作流
- 关于FreeRTOS源码分析的论坛
- 分享一个整理了很多Android开发工具类的链接AndroidUtilCode