正题

题目链接:https://www.luogu.com.cn/problem/P4126


题目大意

给出\(n\)个点\(m\)条边的一张有向图和起点终点。对于每条边求其是否是最小割的可行割/必须割

\(1\leq n\leq 4000,1\leq m\leq 60000\)


解题思路

一些结论吧,首先是可行割,跑一次最大流,然后如果一条边是可行割需要满足

  • 该边满流
  • 残量网络上没有\(x,y\)之间的环

首先满流是显然的,然后第二个结论的话,如果它们之间有环,那么从\(y\)顺着环的方向逆流回去的话那么最大流不变但是这条边的流量减少了。

然后必须割的话也是两个条件

  • 该边满流
  • 残量网络上\(s\)能到\(x\),\(y\)能到\(t\)

这个我直接搬之前的证明了

证明:在残量网络上\(s\)可以到达\(x\)且\(y\)可以到达\(t\)那么说明若该边不割那么\(s\)就可以通过该边到达\(t\)。假设在\(s\)到\(x\)的路上有同样长度的一条道路且割掉后可以使\(s\)到达\(x\)那么在残量网络上该边的流量必定为0,因为切割掉\(x->y\)的流量也必定会经过该边所以在残量网络上\(s\)就不可以到达\(x\)了。所以该假设不成立。

证毕

所以跑完最大流再跑一次\(tarjan\)然后按照上面判就好了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int N=4100,M=6e4+10,inf=1e9;
struct node{
int to,next,w;
}a[M<<1];
int n,m,s,t,tot,cnt,num,ls[N],id[M];
int dep[N],dfn[N],low[N],col[N];
bool ins[N];
stack<int> st;queue<int> q;
void addl(int x,int y,int w){
a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;
return;
}
bool bfs(){
while(!q.empty())q.pop();q.push(s);
memset(dep,0,sizeof(dep));dep[s]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(dep[y]||!a[i].w)continue;
dep[y]=dep[x]+1;
if(y==t)return 1;
q.push(y);
}
}
return 0;
}
int dinic(int x,int flow){
if(x==t)return flow;
int rest=0,k;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(dep[x]+1!=dep[y]||!a[i].w)continue;
rest+=(k=dinic(y,min(flow-rest,a[i].w)));
a[i].w-=k;a[i^1].w+=k;
if(rest==flow)return rest;
}
if(!rest)dep[x]=0;
return rest;
}
void tarjan(int x){
dfn[x]=low[x]=++cnt;
ins[x]=1;st.push(x);
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(!a[i].w)continue;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(ins[y])
low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x]){
int k;++num;
do{
k=st.top();st.pop();
col[k]=num;ins[k]=0;
}while(k!=x);
}
return;
}
signed main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);tot=1;
for(int i=1;i<=m;i++){
int x,y,w;id[i]=tot+1;
scanf("%d%d%d",&x,&y,&w);
addl(x,y,w);
}
while(bfs())
dinic(s,inf);
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=1;i<=m;i++){
int x=a[id[i]^1].to,y=a[id[i]].to;
if(a[id[i]].w==0&&col[x]!=col[y])putchar('1');else putchar('0');putchar(' ');
if(a[id[i]].w==0&&col[x]==col[s]&&col[y]==col[t])putchar('1');else putchar('0');putchar('\n');
}
return 0;
}

P4126-[AHOI2009]最小割【网络流,tarjan】的更多相关文章

  1. P4126 [AHOI2009]最小割(网络流+tarjan)

    P4126 [AHOI2009]最小割 边$(x,y)$是可行流的条件: 1.满流:2.残量网络中$x,y$不连通 边$(x,y)$是必须流的条件: 1.满流:2.残量网络中$x,S$与$y,T$分别 ...

  2. P4126 [AHOI2009]最小割

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

  3. 洛谷P4126 [AHOI2009]最小割

    题目:洛谷P4126 [AHOI2009]最小割 思路: 结论题 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t](否则s到t有通路,能继续 ...

  4. 洛谷$P4126\ [AHOI2009]$最小割 图论

    正解:网络流+$tarjan$ 解题报告: 传送门$QwQ$ $umm$最小割的判定问题$QwQ$,因为并不会做是看的题解才会的,所以也没什么推导过程直接放结论趴$QwQ$ 首先跑个最大流,然后有. ...

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

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

  6. 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan

    题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...

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

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

  8. bzoj 1797: [Ahoi2009]Mincut 最小割【tarjan+最小割】

    先跑一遍最大流,然后对残量网络(即所有没有满流的边)进行tarjan缩点. 能成为最小割的边一定满流:因为最小割不可能割一半的边: 连接s.t所在联通块的满流边一定在最小割里:如果不割掉这条边的话,就 ...

  9. AHOI2009最小割

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

  10. BZOJ1797:[AHOI2009]最小割(最小割)

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

随机推荐

  1. jsoup的Node类

    一.简介 Node类直接继承Object,实现了Cloneable接口,它是一个抽象类,类声明:public abstract class Node extends Object implements ...

  2. JDBC基础篇(MYSQL)——使用statement执行DML语句(insert/update/delete)

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...

  3. OpenCV入门系列教学(三)绘制几何形状及添加文本

    一.绘制简单的几何形状和添加文本 opencv中绘制图形很简单,我们只需要使用下面这些常用函数即可. #画线 cv2.line() #画圆 cv2.circle() #画矩形 cv. rectangl ...

  4. easyexcel

    导出: package com.example.demo.excel.demo0; import com.alibaba.excel.annotation.ExcelProperty; import ...

  5. Java - 记录01_开发环境搭建

    时间:2017-07-04 记录:byzqy 一.什么是JDK JDK(Java Development Kit):Java开发工具集,即Java语言的软件开发工具包. SDK(Software De ...

  6. 利用sql语句复制一条或多条记录

    sql 复制记录insert into article (id,class,title,content) select id,'2',title,content from article where ...

  7. VS C++ C# 混合编程

    创建C++ DLL 注意,32bit和64bit之间不兼容 创建普通dll工程 设置Properties -> Configuration Properties -> General -& ...

  8. Ubuntu16.04 Linux 下安装、配置SSH

    本人在Win7+VMware下利用两个ubuntu虚拟机安装.配置.测试了SSH. 在Server端安装openssh-server. sudo apt-get install ssh # 安装ssh ...

  9. Linux从头学11:理解了这三个概念,才能彻底理解任务管理和任务切换

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  10. WebDriverAgent重签名爬坑记

    接上一篇博文,已经配置好了Xcode环境,那接下来要完成的就是重签名WebDriverAgent.在讲重签名之前,我们还是先来了解下WebDriverAgent,熟悉的朋友,可以直接跳过. WebDr ...