有源匯有上下界最大流詳解(loj116)

2021-08-08 06:08:04 字數 1711 閱讀 3097

例題鏈結

首先吐槽一下放題人(我不知道是不是我理解錯了什麼。)

題目描述裡就乙個上下界然後就說要求最大流。。。

直接建上界然後跑最大流不就完了麼??

實際上原題是這樣的:

求出乙個流使得源點的總流出量等於匯點的總流入量,其他的點滿足流量守恆,而且每條邊的流量滿足上界和下界限制。在這些前提下要求總流量最大。

沒學過無源匯有上下界可行流的看這裡

可行流我不剛學完麼。。想了想。。

上一題是無源匯的,而這道題是有源匯的。

那麼我只要將他變成迴圈流就可以了嘛(其實就是變成無源匯而已)

那麼從匯點到源點建一條流量無限的邊那麼這個圖不就變成無源匯了嘛。

然後建乙個超級源點和超級匯點。(st和ed)

按照上一題的d來連邊。

如果d>0建一條st到i的邊。

如果d<0建一條i到ed的邊。

跟上一題一模一樣(無源匯有上下界可行流)

然後判斷一下從st出發的邊是否滿流(滿流則有解,不滿則無解)

因為第一次跑完最大流之後求得的是流滿下界的流

那麼圖里還剩許多s到t的自由流。

所以剩下的把st和ed刪掉。把與st和ed相連的邊也刪掉。

然後在剩下的圖上跑一次從s到t的最大流即可。

那麼最終答案就是流滿下界的流+殘餘的自由流

**實現:

#include

#include

#include

#include

#include

#include

using

namespace

std;

int n,m,st,ed;

struct node a[41000];int last[210],len;

int work[210],h[210],list[210];

int d[21000],id[21000],chushi[21000];

void ins(int x,int y,int c,int t)

int head,tail;

bool bfs()

}head++;

if(head==ed+1)

head=1;

}if(h[ed]==0)

return

false;

return

true;

}int findflow(int x,int f)

int dinic()

int main()

int llen=len;st=n+1;ed=st+1;

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

ins(t,s,999999999,0); //把有源匯的圖構建成無源匯。

int sum=dinic();

bool bk=true;

for(int k=last[st];k;k=a[k].next)

}if(bk==false)

printf("please go home to sleep\n");

else

return

0;}

感覺網路流這個專題好像很強。運用蠻廣泛的。最重要的問題還是要理解不同的題流量代表的是什麼以及不同的題如何去構圖。

LOJ 116 有源匯上下界最大流

有源匯上下界最大流 模板題。具體講解見 sap演算法或dinic演算法跑出來的是殘量網路上,還能增加多少流量!s t 的最大流解法 建立附加源匯ss,tt。建法詳見上面的博文 並建邊t s,容量為正無窮。跑一遍ss tt最大流,若等於附加出邊容量和,即滿足下界滿流,則繼續求最大流,否則此題無解 無最...

有源匯上下界最大流

a 有源匯有上下界最大流 libreoj 116 給定乙個包含 n 個點 m 條邊的有向圖,每條邊都有乙個流量下界和流量上界。給定源點 s和匯點 t,求源點到匯點的最大流。輸入格式 第一行包含四個整數 n,m,s,t。接下來 m行,每行包含四個整數 a,b,c,d 表示點 a 和 b 之間存在一條有...

有源匯上下界最大流

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