(點選此處檢視原題)
給出n個結點,m條管道,每條管道存在最小流量和最大流量,而且每個結點的流入量等於流出流出量,問這n個結點和m條管道能否形成流量迴圈
經典的無源匯有上下邊界的可行流問題,因為每條邊存在最低流量low和最大流量up,所以每條邊都至少有low流量,我們為每個邊都設定這樣的初始流量,這樣我們就可以將所有邊的下界變為0,上界變成up-low,相當於消滅了下界,而up-low則表示這條邊的容量,和普通最大流問題類似,就將原來有上下邊界的邊轉化為容量為up-low的邊
而這類問題是沒有源點和匯點的,那麼我們再構建一對源點匯點即可。
處理好了上下界問題,我們還需要處理另乙個核心問題:每個點的流入量等於流出量,因為我們為每條邊分配了初始流量,那麼對於每個點,有乙個初始的流入流出量之差 a[i] = i 點的初始流入量-i點的初始流出量
1)如果a[i] > 0 ,說明流入量過多,那麼將多餘的流入量視作由源點流入,即由源點向i建一條容量為a[i]的邊
2)如果a[i] < 0 ,說明輸出量過多,那麼將多餘的流出量視作流入匯點的,即由i向匯點建一條容量為 |a[i]| 的邊
我們用s_out記錄源點的總流出量,如果構建的圖中的最大流 max_flow == s_out ,說明流量由s 流入原圖再流出至匯點的過程中,沒有流量損失,這說明原圖是流量迴圈的,而在求最大流的過程中,我們已經將每條邊的容量調整好了,即滿足條件,那麼每條邊的實際流量就是 下界+實際流量
(因為zoj暫時交不了這個題,所以我是用別人的標稱對拍很久後,得出的**,如果zoj修復了,我會給出通過評測的**)
#include#includeview code#include
#include
#include
#include
#include
#include
#include
#include
#include
#define bug cout << "**********" << endl
#define show(x, y) cout<
using
namespace
std;
typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const ll mod = 1e9 + 7
;const
int max = 1e5 + 10
;const
int max2 = 3e2 + 10
;struct
edge
edge[max
<< 1
];int
n, m, s, t;
inthead[max], tot;
intdis[max], cur[max];
int a[max]; //
記錄i在初始流中的流入量-流出量
intin[max]; //
in 記錄管道的初始流量,即下界;
int id[max]; //
記錄水管i在殘餘網路中的反向邊編號
void
init()
void add(int u, int v, int
flow)
bool
bfs()}}
return
false;}
int dfs(int u,int
flow_in)
}return
flow_out;
}int dinic(int
ans)
return
sum;
}int
main()
int s_out = 0; //
記錄s的流出量
for(int i = 1;i <= n ;i ++)
int max_flow = dinic(n+1
);
if(max_flow ==s_out)
else
}return0;
}
有上下界最大流初步zoj2314
題意 給n個點,及m根pipe,每根pipe用來流躺液體的,單向的,每時每刻每根pipe流進來的物質要等於流出去的物質,要使得m條pipe組成乙個迴圈體,裡面流躺物質。並且滿足每根pipe一定的流量限制,範圍為 li,ri 即要滿足每時刻流進來的不能超過ri 最大流問題 同時最小不能低於li。題解 ...
ZOJ P2314 無源匯點有上下界模版
對於有上下界的網路流來說,我們可以分離出必要弧,然後將必要弧切開,兩端分別連線源點和匯點,原圖有可行解充要於源點或匯點滿流.這樣求下來,只能求出可行流 include include include include include include include using namespace st...
無源匯有上下界可行流
來自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...