你最終會得到圖的一棵生成樹,然後 \(a,b\) 兩點的最小割即是生成樹上 \(a,b\) 間路徑中,權值最小的那條邊。
很神奇。那你怎麼建出這個樹來呢?
首先,最小割等於最大流。你需要乙個 \(\text\) 模板。
故此,你在當前的點集中選定隨意選定兩個點 \(a,b\),求出它們最小割 \(w\),生成樹上增加一條邊 \(a-b:w\)
此時最小割已經把圖分成了兩部分。這兩部分分別遞迴,每個部分也是選兩個點,跑最大流……(注意每次跑最大流時都要把流量復原)
怎麼實現?在solve(l,r)
中。
設 \(dot\) 為當前部分的點集。一開始 \(dot_i=i\)。
然後思考 \(\text\) 的過程:求出最小割後,還會進行一次 \(\text\) 然後返回 \(\text\)。
所以那一次 \(\text\) 中,遍歷過的點就是一部分,\(dep_o\)會有值;沒有遍歷過的則全是初值(比如你memset
的 0 或 -1)。
然後你要乙個臨時陣列 \(dotz\)。設立兩個指標:左指標 \(l=l-1\) 和右指標 \(r=r+1\)。
掃一遍 \(dot\)。對於 \(dep[\ dot_i\ ]\) 有值的, 左指標加一,並 \(dotz_l=dot_i\);否則就右指標減一,並 \(dotz_r=dot_i\)。
最後把 \(dotz\) 複製回 \(dot\)。這樣點集就分成了兩部分: \([l,l],[r,r]\)。分別遞迴即可。
建出樹後,當然是去搞 \(\text\) 以及樹上\(\text\)。然後就能 \(o(\log n)\) 求最小割。
吐槽:洛谷除了 曼哈頓計畫ex 其它的最小割樹題都是板子題……
#include#define rep(i,x,y) for(int i=x;i<=y;++i)
#define per(i,x,y) for(int i=x;i>=y;--i)
#define mar(o,fst,e) for(int e=fst[o];e;e=e[e].nxt)
#define v e[e].to
#define vz ez[e].to
using namespace std;
const int n7=513,m7=3033,inf=int_max-100;
struct dinoe[m7],ez[m7];
int n,m,t,fst[n7],fstd[n7],ecnt0,ecnt=1,dep[n7],que[n7],ds,dt;
int fstz[n7],dept[n7],fc[n7][13],mni[n7][13],dot[n7],dotz[n7];
int rd()
void dedge(int sta,int edn,int w,dino *eh,int *fsth);
fsth[sta]=ecnt;
}void edge(int sta,int edn,int w,dino *eh,int *fsth)
bool bfs()
head++;
} return 0;
}int dfs(int o,int val)
if(dep[v]!=dep[o]+1||e[e].w==0)continue;
int out=dfs(v,min(tot,e[e].w));
e[e].w-=out,e[e^1].w+=out;
tot-=out;
} return val-tot;
}int dinic(int p,int q)
void plant(int l,int r)
rep(i,l,r)dot[i]=dotz[i];
plant(l,zuo),plant(you,r);
}void dfst(int o)
}int dlca(int p,int q)
if(p==q)return fin;
per(i,9,0)
fin=min(fin,min(mni[p][0],mni[q][0]));
return fin;
}int main()
ecnt0=ecnt,ecnt=0;
plant(1,n);
dept[1]=1,dfst(1);
t=rd();
while(t--)
return 0;
}
學習筆記 最小割樹
用於求任意兩個點的最小割 最大流 最小割樹建造方法 類似於分治 在當前點集中選擇任意兩個點作為源點 匯點,跑最小割g 兩個點之間連樹邊,邊權為g 把當前點集中和源點聯通的能到的放進乙個集合裡,與t聯通的放進另乙個集合裡。然後分治下去 注意,每次跑最小割g是在全域性跑。n次最小割 建出樹來之後,任意兩...
學習 最小割樹
及時學習了一波最小割樹。我們有乙個定理 對於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 ...