無源匯有上下界可行流(也就是迴圈流)
模型:乙個網路,求出乙個流,使得每條邊的流量必須》=li且<=hi,
每個點必須滿足總流入量=總流出量(流量守恆)(這個流的特點是迴圈往復,無始無終)
可行流演算法的核心是將乙個不滿足流量守恆的初始流調整成滿足流量守恆的流
流量守恆,即每個點的總流入量=總流出量
如果存在乙個可行流,那麼一定滿足每條邊的流量都大於等於流量的下限
因此我們可以令每條邊的流量等於流量下限,得到乙個初始流,然後建出這個流的殘量網路
(即:每條邊的流量等於這條邊的流量上限與流量下限之差)
這個初始流不一定滿足流量守恆,因此最終的可行流一定是在這個初始流的基礎上增大了一些邊的流量使得所有點滿足流量守恆
因此我們考慮在殘量網路上求出乙個另不滿足流量守恆的附加流,
使得這個附加流和我們的初始流合併之後滿足流量守恆
那麼首先我們需要開乙個陣列a,a[i]表示i在初始流中的流入量-流出量的值
那麼a[i]的正負表示流入量和流出量的大小關係,
a[i]>0,說明附加流的流入量要小於流出量
a[i]<0,說明附加流的流入量要大於流出量
所以a[i]=附加流流出量-流入量
下面就用a[i]表示初始流中i的流入量-流出量
但是dinic演算法能夠求的是滿足流量守恆的有源匯最大流,
不能在原網路上直接求乙個這樣的無源匯且不滿足流量守恆的附加流
注意到附加流是在原網路上不滿足流量守恆的,這啟發我們新增一些原網路之外的邊和點,
用這些邊和點實現「原網路上流量不守恆」的限制
具體地,如果乙個點i在原網路上的附加流中需要滿足流入量》流出量(a[i]<0),
那麼我們需要給多的流入量找乙個去處,因此我們建一條從i出發流量=|a[i]|的邊
如果a[i]>0,也就是我們需要讓附加流中的流出量》流入量,我們需要讓多的流出量有乙個來路,
因此我們建一條指向i的流量=|a[i]|的邊.
當然,我們所新建的從i出發的邊也要有個去處,指向i的邊也要有個來路,
因此我們新建乙個虛擬源點ss和乙個虛擬匯點tt
(雙寫字母是為了和有源匯網路流中的源點s匯點t相區分)
新建的指向i的邊都從ss出發,從i出發的邊都指向tt
乙個點要麼有一條邊指向tt,要麼有一條邊來自ss,
指向tt的邊的總流量上限一定等於ss流出的邊的總流量上限
因為每一條邊對兩個點的a[i]貢獻一正一負大小相等,所以全部點的a[i]之和等於0,
即小於0的a[i]之和的絕對值=大於0的a[i]之和的絕對值.
如果我們能找到乙個流滿足新加的邊都滿流,這個流在原圖上的部分就是我們需要的附加流
那麼怎樣找出乙個新加的邊都滿流的流呢?
可以發現假如存在這樣的方案,這樣的流一定是我們所建出的圖的ss-tt最大流,
所以跑ss到tt的最大流即可
1 #include2 #include3 #include4 #include5 #include6
using
namespace
std;
7const
int maxn=11000;8
const
int inf=0x3f3f3f3f;9
int head[maxn],level[maxn]; //
前者為鄰接表必要資料,後者為dinic的層 資料
10int
in[maxn]; //
一條邊的初始流量(最低值 也就是定為下界)
11int limit[maxn]; //
limit為該點的流量 小於0的時候是流出多
12int bh[maxn]; //
一條邊的反向邊的流量(正向邊流出了多少,反向邊就是多少)
13//
所以用初始的下界流量+上這個方向邊的流量就是最終答案;
14//
那麼為什麼不直接正向呢???
15//
廢話 正向求比較麻煩嘛。 原本的值是可以流的量,正向邊流出去後
16//
那麼答案就是可以流的量減去剩餘的量就是答案;
17//
所以還不如直接求反向呢
18int num; //
鄰接表19
void
init()
2024
struct
node
25g[400000
];28
int bfs(int s,int
t)2943}
44}45return
level[t];46}
47int dfs(int s,int t,int
f)4861}
62}63return
ans;64}
65int dinic(int s,int
t)66
73return
ans;74}
75void build(int u,int v,int
w)76
89int
main()
90105
int sout=0
;106
for(int i=1;i<=n;i++)
112int ans=dinic(s,t);
113//
只有當流入匯點的流量等於流入這個圖的流量,才是有解;
114if(ans==sout)
119else printf("
no\n");
120return0;
121 }
無源匯有上下界可行流
來自loj的模板題 我們可以依照以下幾個步驟來解決這個問題。1.讓所有的邊都流下界數量的水 2.計算每個點流入的水量 流出的水量d x d x d x 3.建超級源點s ss和超級匯點t tt4.對於每個點,若d x 0d x 0 d x 0則連邊s,x d x s,x,d x 如果d x 0d x...
無源匯有上下界可行流 loj模板
loj模板題 思想是 如果存 在可行流 每條邊 必定至少 有下界的 流量 思想是,如果存在可行流,每條邊必定至少有下界的流量 思想是,如果 存在可行 流,每條 邊必定至 少有下界 的流量 那 麼直 接用下屆 填充邊的 流量 那麼直接用下屆填充邊的流量 那麼直接用下 屆填充邊 的流量 每 條邊 的流量...
loj 115 無源匯有上下界可行流
參考部落格 模型 乙個網路,求出乙個流,使得每條邊的流量必須 li且 hi,每個點必須滿足總流入量 總流出量 流量守恆 這個流的特點是迴圈往復,無始無終 這個演算法是有上下界網路流演算法的基礎,只要深刻理解這個演算法其他演算法也就水到渠成,因此我用大篇幅力圖將這個演算法的思想和細節闡述清楚.可行流演...