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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[bzoj1797][Ahoi2009]Mincut 最小割

發布時間:2025/7/14 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [bzoj1797][Ahoi2009]Mincut 最小割 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自FallDream的博客,未經允許,請勿轉載,謝謝qaq


A,B兩個國家正在交戰,其中A國的物資運輸網中有N個中轉站,M條單向道路。設其中第i (1≤i≤M)條道路連接了vi,ui兩個中轉站,那么中轉站vi可以通過該道路到達ui中轉站,如果切斷這條道路,需要代價ci。現在B國想找出一個路徑切斷方案,使中轉站s不能到達中轉站t,并且切斷路徑的代價之和最小。? 小可可一眼就看出,這是一個求最小割的問題。但愛思考的小可可并不局限于此。現在他對每條單向道路提出兩個問題:?? 問題一:是否存在一個最小代價路徑切斷方案,其中該道路被切斷?? 問題二:是否對任何一個最小代價路徑切斷方案,都有該道路被切斷??? 現在請你回答這兩個問題。

n<=4000 m<=60000

題解:先跑一次最小割,然后在殘量網絡上tarjan,用所有沒滿流的邊縮點。

由于是最小割,所以顯然ST不在同一塊

一條邊如果沒有滿流,那么它就不可能被割了。在這基礎上:

  一條邊可以被割當且僅當連接的兩個點所屬的塊不同。

  一條邊一定被割當且僅當連接的兩個點分別和S,T同塊。

證明我不會,轉一個鏼爺(jcvb)的題解:

<==將每個SCC縮成一個點,得到的新圖就只含有滿流邊了。那么新圖的任一s-t割都對應原圖的某個最小割,從中任取一個把id[u]和id[v]割開的割即可證明。

?< ==:假設將(u,v)的邊權增大,那么殘余網絡中會出現s->u->v->t的通路,從而能繼續增廣,于是最大流流量(也就是最小割容量)會增大。這即說明(u,v)是最小割集中必須出現的邊。

#include<iostream> #include<cstdio> #include<cstring> #define ll long long #define MN 4000 #define INF 2000000000 using namespace std; inline int read() {int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f; }int n,m,S,T,head[MN+5],cnt=1,d[MN+5],c[MN+5],q[MN+5],top,dn=0,dfn[MN+5],low[MN+5],bel[MN+5],cc=0; struct edge{int from,to,next,w;}e[120005];inline void ins(int f,int t,int w) {e[++cnt]=(edge){f,t,head[f],w};head[f]=cnt;e[++cnt]=(edge){t,f,head[t],0};head[t]=cnt; }int dfs(int x,int f) {if(x==T)return f;int used=0;for(int&i=c[x];i;i=e[i].next)if(e[i].w&&d[e[i].to]==d[x]+1){int w=dfs(e[i].to,min(f-used,e[i].w));used+=w;e[i].w-=w;e[i^1].w+=w;if(used==f)return used;}return d[x]=-1,used; }bool bfs() {memset(d,0,sizeof(d));int i,j;for(d[q[top=i=1]=S]=1;i<=top;i++)for(j=c[q[i]]=head[q[i]];j;j=e[j].next)if(e[j].w&&!d[e[j].to])d[q[++top]=e[j].to]=d[q[i]]+1;return d[T]; }void tarjan(int x) {dfn[x]=low[x]=++dn;q[++top]=x;for(int i=head[x];i;i=e[i].next)if(e[i].w){if(!dfn[e[i].to]) tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);elseif(!bel[e[i].to]) low[x]=min(low[x],dfn[e[i].to]); }if(dfn[x]==low[x])for(++cc;q[top+1]!=x;--top)bel[q[top]]=cc; }int main() {n=read();m=read();S=read();T=read();for(int i=1;i<=m;i++){int u=read(),v=read(),c=read();ins(u,v,c);}while(bfs()) dfs(S,INF); top=0;memset(q,0,sizeof(q));for(int i=1;i<=n;i++)if(!dfn[i]) tarjan(i);for(int i=2;i<=cnt;i+=2)printf("%d %d\n",!e[i].w&&bel[e[i].from]!=bel[e[i].to],bel[e[i].from]==bel[S]&&bel[e[i].to]==bel[T]);return 0; }

?

轉載于:https://www.cnblogs.com/FallDream/p/bzoj1797.html

總結

以上是生活随笔為你收集整理的[bzoj1797][Ahoi2009]Mincut 最小割的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。