日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P4126-[AHOI2009]最小割【网络流,tarjan】

發(fā)布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4126-[AHOI2009]最小割【网络流,tarjan】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P4126


題目大意

給出nnn個點(diǎn)mmm條邊的一張有向圖和起點(diǎn)終點(diǎn)。對于每條邊求其是否是最小割的可行割/必須割

1≤n≤4000,1≤m≤600001\leq n\leq 4000,1\leq m\leq 600001n4000,1m60000


解題思路

一些結(jié)論吧,首先是可行割,跑一次最大流,然后如果一條邊是可行割需要滿足

  • 該邊滿流
  • 殘量網(wǎng)絡(luò)上沒有x,yx,yx,y之間的環(huán)

首先滿流是顯然的,然后第二個結(jié)論的話,如果它們之間有環(huán),那么從yyy順著環(huán)的方向逆流回去的話那么最大流不變但是這條邊的流量減少了。

然后必須割的話也是兩個條件

  • 該邊滿流
  • 殘量網(wǎng)絡(luò)上sss能到xxxyyy能到ttt

這個我直接搬之前的證明了

證明:在殘量網(wǎng)絡(luò)上sss可以到達(dá)xxxyyy可以到達(dá)ttt那么說明若該邊不割那么sss就可以通過該邊到達(dá)ttt。假設(shè)在sssxxx的路上有同樣長度的一條道路且割掉后可以使sss到達(dá)xxx那么在殘量網(wǎng)絡(luò)上該邊的流量必定為0,因?yàn)榍懈畹?span id="ozvdkddzhkzd" class="katex--inline">x?>yx->yx?>y的流量也必定會經(jīng)過該邊所以在殘量網(wǎng)絡(luò)上sss就不可以到達(dá)xxx了。所以該假設(shè)不成立。
證畢

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


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; }

總結(jié)

以上是生活随笔為你收集整理的P4126-[AHOI2009]最小割【网络流,tarjan】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。