link
媽的**題解話不說清楚,不早說第二輪dinic的時候要去掉匯源邊,害得我白白地多花費了乙個小時。就離譜,這麼乙個網路流二次模板我寫了一下午。暈了。
說回題目本身。建模是小事,主要是那個所謂的有源匯上下界最大流怎麼求。
首先是無源匯上下界可行流怎麼搞?可以想到假如強制讓每一條邊流滿下界肯定是解題的一部分。而這樣做顯然會出現問題,比如假如乙個點的前驅下界比你的上界都牛逼,你能怎麼辦,而這種情況是上述想法所考慮不到的。於是可以考慮在上述想法基礎上給每個點維護乙個w值,記錄假如強制下界流滿後每個節點的正負盈虧,正的代表流進來的太多了,反之就是庫存空虛需要補給。於是現在問題就變成了如何讓這些精力過剩的節點分配出來一些流量給那些可憐的小傢伙呢?
眾所周知圖論中有乙個超級源點和超級匯點的技巧。我們重新審視一下上面提出的那個問題:我們認為圖中一些節點是可以向外進行貢獻的,另一些節點是需要別人對它貢獻的,而我們的目標是剛好補齊它們的差距使得每乙個點都可以不多不少,這一點可以考慮建立超級源點,連線精力過剩的點;同時建立超級匯點,連線所有精力不足的點,然後跑最大流。如果最大流剛好等於所有點欠下的流量之和,則可以判定我們找到了乙個可行流。
然後如何解決有源匯的問題呢?考慮連一條從匯點到源點(沒有超級二字)邊權極大的邊,然後按照相同的方式跑最大流即可。
那最大流呢?可以想到在經歷了上述兩個步驟之後,我們得到了乙個方案,保證每條邊都達到了下限且每個節點都達到了收支平衡。接下來我們想讓它的流盡量多,可以直接單純滴跑最大流即可。需要注意的是上面那條從匯點連向源點的邊在本次步驟中一定要刪去,否則會死得很慘。我就是乙個例子。
祭奠我平白逝去的乙個下午。
#include#include//#define zczc
using namespace std;
const int d=400;
const int m=1010;
const int c=310;
const int maxn=1e9;
inline void read(int &wh)
while(w<='9'&&w>='0')
wh*=f;return;
}inline int min(int s1,int s2)
while(check(ss,tt))ans+=dinic(ss,maxn,tt);
if(ans!=as)
e[3].v=e[2].v=0;
while(check(s,t))ans+=dinic(s,maxn,t);
printf("%d\n\n",ans);
}void init()
signed main()
for(int i=1;i<=m;i++)
} solve(); }
return 0;
}
有源匯上下界最大流
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...
有源匯的上下界最大流
主要由兩種做法 1 二分乙個流量,然後跑乙個最大流,看有沒有能滿足的可行流,能滿足的流量的最大值就是答案了,複雜度 單次網路流複雜度 log最大流量 反之我是不想寫這個的,感覺寫起很麻煩,而且二分的邊界也不好調 看方法二就可以了 2 首先無論如何我們都需要先跑一次可行流的 不然連能不能流通都不知道 ...