有源匯有上下界最小流 (ZQU 1592

2022-06-02 08:00:11 字數 1942 閱讀 3248

這道題跟求最大流的時候差不多。

都是先構造可行流,然後判斷是否可行,

可行的話,就利用殘餘流量,構造從匯點t跑到源點s的最大流,

如何求出答案呢。

在第一次求可行流的dinic後,跟求最大流的時候一樣,從t到s是可行流的流量;

這個時候t到s的反向邊,也就是s到t的流量就是t到s流的量(因為t到s定義權值為inf,要從這條邊算出來,得用inf去減到這條邊剩下的才是答案,有點麻煩)

所以反向邊是個便捷的求法。

所以在第一次dinic之後,t到s的反向便的流量就是可行流的流量;

然後我們再從t到s跑最大流,看最大能跑掉多少,就是最後的答案。 (這裡肯定不會影響可行流!,因為已經在第一次dinic的時候保證了可行(即sum==tmpp))

求第二次dinic的時候,要將s跟t之間的邊給去掉。

1 #include2 #include

3 #include4 #include5 #include6

using

namespace

std;

7 typedef long

long

ll;8

const ll maxn=51000;9

const ll inf=0x3f3f3f3f3f3f3f3f;10

ll vis[maxn];

11 ll head[maxn],level[maxn]; //

前者為鄰接表必要資料,後者為dinic的層 資料

12 ll in[maxn]; //

一條邊的初始流量(最低值 也就是定為下界)

13 ll limit[maxn]; //

limit為該點的流量 小於0的時候是流出多

14//

ll bh[maxn];

//一條邊的反向邊的流量(正向邊流出了多少,反向邊就是多少)

15//

所以用初始的下界流量+上這個方向邊的流量就是最終答案;

16//

那麼為什麼不直接正向呢???

17//

廢話 正向求比較麻煩嘛。 原本的值是可以流的量,正向邊流出去後

18//

那麼答案就是可以流的量減去剩餘的量就是答案;

19//

所以還不如直接求反向呢

20 ll num; //

鄰接表21

void

init()

2226

struct

node

27g[maxn*12

];30

ll bfs(ll s,ll t)

3145}46

}47return

level[t];48}

49ll dfs(ll s,ll t,ll f)

5064}65

}66//if(ans==0) level[s]=0;

67return

ans;68}

69ll dinic(ll s,ll t)

7078

return

ans;79}

80void

build(ll u,ll v,ll w)

8194

intmain()

95107 ll s=0;ll t=n+1

;108 ll sum=0

;109

for(ll i=1;i<=n;i++)

113build(t,s,inf);

114//

其實這裡應該有上面的limit的變化 只是因為這裡的w1為0,所以省略不寫。

115 ll tmpp=dinic(s,t);

116if(tmpp!=sum) printf("

please go home to sleep\n");

117else

123return0;

124 }

117 有源匯有上下界最小流

題目描述 n nn 個點,m mm 條邊,每條邊 e ee 有乙個流量下界 lower e text e lower e 和流量上界 upper e text e upper e 給定源點 s ss 與匯點 t tt,求源點到匯點的最小流。輸入格式 第一行兩個正整數 n nn m mm s ss t...

有源匯有上下界最大 最小流

建圖還是要想一想的.寫一下吧 首先根據有源匯可行流建圖,正向附加邊滿流證明有可行流 然後在這個殘量網路上刪掉 t,s,oo 這條邊,跑 s t 最大流就是最大流,t s 最大流就是最小流 include define int long long define ll long long define ...

有源匯上下界最小流 模板

這只是 其中一種 做法 這只是其中一種做法 這只是其中一 種做法 我暫時還沒有理解,只是先放個模板而已 首 先還 是根據下 界來建圖 原圖源 點s,匯 點t 首先還是根據下界來建圖,原圖源點s,匯點t 首先還是根據 下界來建 圖,原圖 源點s,匯點t 然 後因 為流量守 恆,新建 超級源s 1和超級...