嚴格次小生成樹學習筆記

2022-05-14 14:47:56 字數 1935 閱讀 8778

嚴格次小生成樹,顧名思義,就是在聯通圖上選擇一些邊構成一棵樹,使這棵樹邊權和嚴格次小。

要求嚴格次小生成樹,我們就要先求出最小生成樹(\(prim\)和\(kruskal\)等演算法都可以,我用的是\(kruskal\)),在求最小生成樹的過程中,還要給每條使用過的邊打乙個標記,**如下:

inline void kruskal()//求最小生成樹

\)來記錄\(i\)的第\(2^j\)個祖先,然後還要額外加上兩個陣列\(max1_\)和\(max2_\)分別表示節點\(i\)到其第\(2^j\)個祖先的路徑上邊權最大的邊的邊權邊權嚴格次大的邊的邊權

為什麼只需記錄最大和嚴格次大的邊權,而不需記錄第三大、第四大、第五大?

證明:由於最小生成樹基於貪心,因此,這些邊中最大的邊也不會大於新加入的這條邊,所以嚴格次大的邊一定小於新加入的這條邊。

既然這樣,對於新加入的一條邊\((u,v)\),我們只需在求出它們的\(lca\)的同時計算出\(u\)和\(v\)到\(lca(u,v)\)的路徑上小於\((u,v)\)權值的最大邊權即可。

**如下:

inline ll max(ll x,ll a,ll b,ll val)//求出a到其第2^b個父親的路徑上邊權小於val的最大值與x的最大值

inline ll get(ll x,ll y,ll val)//求出x和y路徑之間小於val的最大邊權

最後,貼一下洛谷板子題的**:

#include#define max(x,y) ((x)>(y)?(x):(y))

#define min(x,y) ((x)<(y)?(x):(y))

#define abs(x) ((x)<0?-(x):(x))

#define ll long long

#define ull unsigned long long

#define swap(x,y) (x^=y,y^=x,x^=y)

#define tc() (a==b&&(b=(a=ff)+fread(ff,1,100000,stdin),a==b)?eof:*a++)

#define pc(ch) (pp_<100000?pp[pp_++]=(ch):(fwrite(pp,1,100000,stdout),pp[(pp_=0)++]=(ch)))

#define n 100000

#define m 300000

#define mod 31011

ll pp_=0;char ff[100000],*a=ff,*b=ff,pp[100000];

using namespace std;

ll n,m,depth[n+5],f[n+5],fa[n+5][20],max1[n+5][20],max2[n+5][20];

struct edge

e[m+5];

vectorv[n+5];

inline void read(ll &x)

inline void write(ll x)

inline ll getfa(ll x)

inline bool cmp(edge x,edge y)

inline ll get(ll x,ll y,ll val)

int main()

for(init(),i=1;i<=m;++i)

if(!e[i].used) t=get(e[i].from,e[i].to,e[i].val),ans=min(ans,res+e[i].val-t);

return write(ans),fwrite(pp,1,pp_,stdout),0;

}

嚴格次小生成樹

顧名思義。生成樹,邊權和嚴格小於最小生成樹 一定和最小生成樹有關係。實際上,有 結論1 嚴格次小生成樹只在最小生成樹上改動一條邊 證明 改動一條邊有意義的話,必然改完這條邊,總和變大。那麼這至少是嚴格次小生成樹的最大值。再改一條也沒有意義。結論2 改動的那條邊w,一定是新加入的那條邊覆蓋的樹鏈的最大...

總結 嚴格 次小生成樹

首先需要了解什麼是最小生成樹,還要知道什麼是倍增 求lca 上面的東西如果了解了,就可以開始進入學習的路途了 用不是最小生成樹上的邊去更新答案.對於每乙個倍增跳上去的,要維護兩個東西 我們考慮一下對於每一條邊 不在最小生成樹上 如果要把它加入答案,如何更新?mst 路徑最大值 邊權.然後這個東西就可...

瘋子的演算法總結11 次小生成樹 嚴格次小生成樹

首先,我這一題的思路是倍增lca kruskal 首先,kruskal求最小生成樹 不會的戳這裡 求次小生成樹 倍增 lca 關鍵在於次小生成樹怎麼求 問自己一些問題 怎麼求不嚴格次小生成樹 不嚴格次小生成樹為什麼不嚴格 方法每次選擇u v之間的邊,前提是最小生成樹上不存在的邊,添邊之後刪去較短邊,...