學習筆記 最小割樹

2022-02-05 14:07:01 字數 1995 閱讀 7395

用於求任意兩個點的最小割(最大流)

最小割樹建造方法:

類似於分治

在當前點集中選擇任意兩個點作為源點、匯點,跑最小割g

兩個點之間連樹邊,邊權為g

把當前點集中和源點聯通的能到的放進乙個集合裡,與t聯通的放進另乙個集合裡。然後分治下去

注意,每次跑最小割g是在全域性跑。

n次最小割

建出樹來之後,任意兩點的最小割,就是兩點樹上路徑的邊權最小值。

證明不知。

可以證明最小是這個最小值,但是感覺不能證明能取到=。

**:(找聯通塊的話,用dfs染色即可)

【模板】最小割樹(gomory-hu tree)

#include#define il inline

#define reg register int

#define numb (ch^'0')

using

namespace

std;

typedef

long

long

ll;il

void rd(int &x)

namespace

miraclee[

2*m],bian[2*m];

struct

bbbbbb[m];

int hd[n],cnt=1

;void add(int x,int y,int

z)int

pre[n],tot;

void add_c(int x,int y,int

z)int

d[n];

int dfs(int x,int

flow)

}return flow-res;

}int

q[n],l,r;

bool

bfs()}}

return

false;}

int dinic(int x,int

y)

int maxflow=0

;

int flow=0

;

while

(bfs())

return

maxflow;

}int

ptr;

intmem[n],b[n],co[n];

bool

in[n];

void fin(intx)}

void divi(int l,int

r)

for(reg i=l;i<=r;++i)

divi(l,pp);divi(qq,r);

}int fa[n][13],mi[n][13

];int

dep[n];

void dfs2(int x,int

deep)

}int slo(int x,int

y) }

if(x==y) return

ans;

for(reg i=12;i>=0;--i)

}ans=min(ans,min(mi[x][0],mi[y][0

]));

return

ans;

}int

main()

for(reg i=1;i<=n;++i) mem[i]=i;

divi(

1,n);

dfs2(

1,1);

for(reg j=1;j<=12;++j)

}intt;

rd(t);

dep[

0]=-1

;

while(t--)

return0;

}}signed main()

/*author: *miracle*

date: 2018/12/16 22:45:00

*/

還有兩個模板題;[zjoi2011]最小割

[cqoi2016]不同的最小割

最小割樹 學習筆記

你最終會得到圖的一棵生成樹,然後 a,b 兩點的最小割即是生成樹上 a,b 間路徑中,權值最小的那條邊。很神奇。那你怎麼建出這個樹來呢?首先,最小割等於最大流。你需要乙個 text 模板。故此,你在當前的點集中選定隨意選定兩個點 a,b 求出它們最小割 w 生成樹上增加一條邊 a b w 此時最小割...

學習 最小割樹

及時學習了一波最小割樹。我們有乙個定理 對於n個點的一張圖,本質不同的最小割最多只有n 1種。那麼我們一定可以將原圖構成一棵樹,使得原圖中兩個點 x,y 的最小割等於這棵樹上兩點 x,y 的最小割。構造方法 我們選取集合中的兩個點 x,y 然後跑乙個最小割後將集合劃分為x集合 x可以在殘量網路上到達...

最小割樹 Luogu P4897 最小割樹

給定乙個nn個點mm條邊的無向連通圖,多次詢問兩點之間的最小割 兩點間的最小割是這樣定義的 原圖的每條邊有乙個割斷它的代價,你需要用最小的代價使得這兩個點不連通 輸入格式 第一行兩個數n,mn,m 接下來mm行,每行33個數u,v,wu,v,w,表示有一條連線uu與vv的無向邊,割斷它的代價為ww ...