bzoj1797: [Ahoi2009]Mincut 最小割(网络流,缩点)
传送门
首先肯定要跑一个最小割也就是最大流
然后我们把残量网络tarjan,用所有没有满流的边来缩点
一条边如果没有满流,那它就不可能被割了
一条边如果所属的两个强联通分量不同,它就可以被割
一条边如果所属的两个点一个与源点同块,一个与汇点同块,那么它就可以一定在最小割集合中
为啥我也不会证,直接搬一下隔壁的吧
1.将每个SCC缩成一个点,得到的新图就只含有满流边了。那么新图的任一s-t割都对应原图的某个最小割,从中任取一个把id[u]和id[v]割开的割即可证明。
2.假设将(u,v)的边权增大,那么残余网络中会出现s->u->v->t的通路,从而能继续增广,于是最大流流量(也就是最小割容量)会增大。这即说明(u,v)是最小割集中必须出现的边。
//minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int head[N],Next[M],ver[M],edge[M],tot=;
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=;
}
int dep[N],cur[N],s,t,n,m;
queue<int> q;
bool bfs(){
memset(dep,-,sizeof(dep));
while(!q.empty()) q.pop();
for(int i=;i<=n;++i) cur[i]=head[i];
q.push(s),dep[s]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(dep[v]<&&edge[i]){
dep[v]=dep[u]+,q.push(v);
if(v==t) return true;
}
}
}
return false;
}
int dfs(int u,int limit){
if(u==t||!limit) return limit;
int flow=,f;
for(int i=cur[u];i;i=Next[i]){
int v=ver[i];cur[u]=i;
if(dep[v]==dep[u]+&&(f=dfs(v,min(limit,edge[i])))){
flow+=f,limit-=f;
edge[i]-=f,edge[i^]+=f;
if(!limit) break;
}
}
if(!flow) dep[u]=-;
return flow;
}
int dfn[N],low[N],st[N],c[N],top,cnt,num;
void tarjan(int u){
dfn[u]=low[u]=++num,st[++top]=u;
for(int i=head[u];i;i=Next[i])
if(edge[i]){
int v=ver[i];
if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);
else if(!c[v]) cmin(low[u],dfn[v]);
}
if(dfn[u]==low[u])
for(++cnt;st[top+]!=u;--top) c[st[top]]=cnt;
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read(),s=read(),t=read();
for(int i=;i<=m;++i){
int u=read(),v=read(),e=read();add(u,v,e);
}
while(bfs()) dfs(s,inf);
for(int i=;i<=n;++i)
if(!dfn[i]) tarjan(i);
for(int i=;i<=tot;i+=){
printf("%d %d\n",!edge[i]&&c[ver[i]]!=c[ver[i^]],c[ver[i^]]==c[s]&&c[ver[i]]==c[t]);
}
return ;
}
bzoj1797: [Ahoi2009]Mincut 最小割(网络流,缩点)的更多相关文章
- BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )
先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...
- bzoj1797: [Ahoi2009]Mincut 最小割
最大流+tarjan.然后因为原来那样写如果图不连通的话就会出错,WA了很久. jcvb: 在残余网络上跑tarjan求出所有SCC,记id[u]为点u所在SCC的编号.显然有id[s]!=id[t] ...
- bzoj1797: [Ahoi2009]Mincut 最小割(最小割+强联通tarjan)
1797: [Ahoi2009]Mincut 最小割 题目:传送门 题解: 感觉是一道肥肠好的题目. 第二问其实比第一问简单? 用残余网络跑强联通,流量大于0才访问. 那么如果两个点所属的联通分量分别 ...
- 【bzoj1797】[Ahoi2009]Mincut 最小割 网络流最小割+Tarjan
题目描述 给定一张图,对于每一条边询问:(1)是否存在割断该边的s-t最小割 (2)是否所有s-t最小割都割断该边 输入 第一行有4个正整数,依次为N,M,s和t.第2行到第(M+1)行每行3个正 整 ...
- BZOJ1797 [Ahoi2009]Mincut 最小割 【最小割唯一性判定】
题目 A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站,如果切断这条道路 ...
- 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割
结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. #include ...
- 【BZOJ-1797】Mincut 最小割 最大流 + Tarjan + 缩点
1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1685 Solved: 724[Submit] ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割
1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2076 Solved: 885[Submit] ...
- BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan
BZOJ_1797_[Ahoi2009]Mincut 最小割_最小割+tarjan Description A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤ ...
随机推荐
- 提示ORA-28000 the account is locked
1.启动项目的时候提示ORA-28000 the account is locked. 2. 这是因为用户被锁定了. 查询FAILED_LOGIN_ATTEMPTS参数默认值,这个参数限制了从第一次登 ...
- python 基础例子 双色球 查询天气 查询电话
# 随机生成双色球import random# 随机数 1-16之间# r = random.randint(1,16)# print(r)phone_numbers_str = "匪警[1 ...
- Selenium工具爬取商品
selenium是一个优秀的自动化测试工具,支持多种语言,具体介绍参考官方文档:https://www.seleniumhq.org/docs/. 下面我们使用selenium工具模拟用户点击商品详情 ...
- 一个复杂关联的sql
在项目中遇到了一个比较复杂关系的sql,关联关系有些模糊,现在梳理一下 sql如下: SELECT TRAN.TRANS_DATE, TRAN.TRANS_TIME, TRAN.BUSI_TRAC_C ...
- KeyValuePair<string, string>
; #region CUP Method /// <summary> /// 请求与响应的超时时间 /// </summary> static public int Timeo ...
- regex 正则分割字符串
string _content=adak.sjdkajskj爱25教:师的656教案时; string en=@"\.|56|25";//单个[asj]分别以a,s,j为分隔符. ...
- linux 操作系统安装
操作系统安装 安装虚拟机软件:一路Next即可 VMWare:如果14版本不支持你的CPU,就换成12版本 Virtual Box:比VMWare小很多 安装ubuntu操作系统:比较美观,实用性强 ...
- python 修改、读取图片元数据
图片元数据 图片元数据(metadata)是嵌入到图片文件中的一些标签.比较像文件属性,但是种类繁多.常见的几种标准有: EXIF:通常被数码相机在拍摄照片时自动添加,比如相机型号.镜头.曝光.图片尺 ...
- 三、DQL语言
目录 一.基础查询 (一)语法 (二)特点 (三)示例 二.条件查询 (一)语法 (二)筛选条件的分类 三.排序查询 (一)语法 (二)特点 四.常见函数 (一)介绍 (二)分类 五.单行函数 (一) ...
- Oracle和MySql的分页查询区别和PL/SQL的基本概念
Oracle和MySql的分页查询区别: Oracle的分析查询,之前Oracle的分页是使用伪列 ROWNUM 结合子查询实现,mysql的分页更简单,直接使用 LIMIT 关键字就可以实现 ...