hdu 3987 求割邊最少的最小割

2021-06-22 03:08:32 字數 1077 閱讀 7045

題目是求邊數最少的最小割集。

網上看到了兩種方法,粘一下。

第一種:

建邊的時候每條邊權 w = w * (e + 1) + 1;

這樣得到最大流 maxflow / (e + 1) ,最少割邊數 maxflow % (e + 1)

道理很簡單,如果原先兩類割邊都是最小割,那麼求出的最大流相等

但邊權變換後只有邊數小的才是最小割了

乘(e+1)是為了保證邊數疊加後依然是餘數,不至於影響求最小割的結果

因為假設最小割=k,那麼現在新圖的最小割為k*(e+1)+p,p為割的邊數,本質上是,原來你割一條邊,需要代價,

由於你要求邊數最小 所以你多割一條邊,就多一的代價,但是這個代價不足以影響到原來的代價。

原來割一條邊,代價xi,現在割一條邊,代價xi*a+1,只要讓a>m+1,m為邊數,即使割了所有的邊,自己加上去的代價也就m

第二種:

建圖,得到最大流後,圖中邊若滿流,說明該邊是最小割上的邊

再建圖,原則:滿流的邊改為容量為 1 的邊,未滿流的邊改為容量 inf 的邊,然後最大流即答案

算出那些可以在最小割集中的邊,然後變成乙個求最小割邊的網路流,那些不可能在最小割集中的邊,我們就不能割它們,所以cost為inf

另外,最小割邊集合增廣路沒啥關係,乙個錯誤觀點:

一條增廣路上面只要割一條邊就好。例如:

s->1 2

1->2 1

1->3 1

2->t oo

3->t oo

這當然是兩條增廣路,但是最小割邊當然是一條。

#include #include #include using namespace std;

#define maxn 10000

#define inf 1ll<<60

#define mod 100001

#define maxm 500000

int n,m;

int level[maxn],que[maxn];

int head[maxn],lon;

__int64 min(__int64 a,__int64 b)

{ if(a

hdu 3987 求割邊最少的最小割

割邊必然是滿流的邊 方法一 重新建圖,將滿流的邊改為容量為1,非滿流的邊改為容量為inf。再跑一邊最大流就是割邊的個數。要注意的是,改圖的時候,應該對正向邊進行判斷,cap 0則為滿流 方法二 建圖時,每條邊的cap cap e 1 1,則最後的最小割就是max flow e 1 割邊的個數就是ma...

hdu 3987 最小割的邊數

題意 給出一張有n個點的圖,有的邊又向,有的邊無向,現在要你破壞一些路,使得從點0無法到達點n 1。破壞每條路都有乙個代價。求在代價最小的前提下,最少需要破壞多少條道路。就是說求在最小割的前提下,最小的割邊數 解題思路 求最小割很好辦,跑一邊最大流即可,但關鍵是要求最小割邊數。這裡用到了乙個結論 最...

HDU 3987 最小割模型

讀完題後,就知道是最小割了,最小割 最大流,但是題目又說要最少邊的最小割,輸出邊的個數 這樣建邊得時候就要換種方式了,將邊權w變為w e 1 1,這時候求出的最大流實際上附帶了乙個資訊,就是邊的個數,最後的結果直接mod e 1 即可 id cugb wwj prog lang c include ...