\(n\)個點\(m\)條邊的一張圖,每條邊有流量上下限制,求源點到匯點的最大流。
先別急著求上面那個,考慮一下怎麼求無源點匯點的上下界可行流。
可以考慮先把下限流滿,這樣就會出現有的點流量不均衡的問題,考慮每個點除了下限以外還有附加流量,這些附加流量會最多佔能每條邊\(r-l\)這麼多的流量,可以先建立一張每條流量都是\(r-l\)的圖。
定義乙個點的\(d_i\)為該點的入度減去出度(流入的流量減去流出的流量),然後對於乙個點如果它的\(d_i\)大於\(0\),那麼它需要向其他點補充流量,建立乙個超級源點\(s\)向它連邊,流量為\(d_i\)。同理如果乙個點的\(d_i\)小於\(0\)就連向超級匯點\(t\)。
這樣就搞定了無源點匯點的上下界可行流問題了。
然後考慮有源匯點\(s,t\)怎麼辦,那麼也就是\(t\)可以無限接受,\(s\)可以無限輸送。那麼如果\(t\)向\(s\)連一條\(inf\)的邊,那麼就可以保證\(s,t\)的功能又能保證流量守恆了。
之後直接和無源點匯點的一樣做就好了。
然後要求最大流,先跑一次有沒有可行的再考慮流量能夠浮動的範圍,此時我們需要在剛剛的殘量網路上找從\(s\)到\(t\)的增廣路來增大\(s\)到\(t\)的流量,那麼刪掉剛剛\(t->s\)的邊然後跑\(s->t\)的最大流就好了。
最小流的話就是從\(t->s\)跑最大流
#include#include#include#includeusing namespace std;
const int n=210,inf=1e9;
struct nodea[41000];
int n,m,tot,in[n],out[n],d[n];
int ls[n],cur[n],dep[n];
queueq;
void addl(int x,int y,int w)
bool bfs(int s,int t)
}return 0;
}int dinic(int x,int flow,int t)
if(!rest)dep[x]=0;
return rest;
}int main()
for(int i=1;i<=n;i++)
if(d[i]>0)addl(s,i,d[i]),sum+=d[i];
else addl(i,t,-d[i]);
addl(t,s,inf);
while(bfs(s,t))
ans+=dinic(s,inf,t);
if(ans!=sum)
return puts("please go home to sleep");
ans=a[tot].w;a[tot].w=a[tot^1].w=0;
while(bfs(s,t))
ans+=dinic(s,inf,t);
printf("%d\n",ans);
}
Loj 116 模板 有源匯有上下界最大流
n nn個點m mm條邊的一張圖,每條邊有流量上下限制,求源點到匯點的最大流。先別急著求上面那個,考慮一下怎麼求無源點匯點的上下界可行流。可以考慮先把下限流滿,這樣就會出現有的點流量不均衡的問題,考慮每個點除了下限以外還有附加流量,這些附加流量會最多佔能每條邊r l r lr l這麼多的流量,可以先...
LOJ116 有源匯有上下界最大流(模板題)
點此看題面 大致題意 給你每條邊的流量上下界,讓你先判斷是否存在可行流。若存在,則輸出最大流。在做此題之前,最好先去看看這道題目 loj115 無源匯有上下界可行流。首先,我們先跑一遍無源匯上下界可行流,同時判斷是否有解。等會兒,這題是有源匯的,而剛才提到的可行流是無源匯的,怎麼辦?答 沒關係!直接...
LOJ 116 有源匯上下界最大流
有源匯上下界最大流 模板題。具體講解見 sap演算法或dinic演算法跑出來的是殘量網路上,還能增加多少流量!s t 的最大流解法 建立附加源匯ss,tt。建法詳見上面的博文 並建邊t s,容量為正無窮。跑一遍ss tt最大流,若等於附加出邊容量和,即滿足下界滿流,則繼續求最大流,否則此題無解 無最...