嚴格次小生成樹 BJWC2010

2022-02-24 23:41:56 字數 4562 閱讀 4304

原文必點

原題鏈結

給定一張\(n\) 個點$ m $條邊的無向圖,求無向圖的嚴格次小生成樹。

設最小生成樹的邊權之和為\(sum\),嚴格次小生成樹就是指邊權之和大於\(sum\)的生成樹中最小的乙個。

輸入格式

第一行包含兩個整數\(n\)和\(m\)。

接下來\(m\)行,每行包含三個整數\(x,y,z\),表示點\(x\)和點\(y\)之前存在一條邊,邊的權值為\(z\)。

輸出格式

包含一行,僅乙個數,表示嚴格次小生成樹的邊權和。(資料保證必定存在嚴格次小生成樹)

資料範圍

\[n \le 10^5 \\\\

m \le 3*10^5

\]輸入樣例:

5 6 

1 2 1

1 3 2

2 4 3

3 5 4

3 4 3

4 5 6

輸出樣例:
11
題意理解

要你構造一棵\(n\)個節點的嚴格次小生成樹.

演算法解析

分析條件

題目中給出的關鍵點,就是嚴格和次小.

什麼是嚴格

就是題目強制要求嚴格單調性,不可以有\(=\)號的出現.

什麼是次小

我們應該都知道,最小生成樹,它要求邊集合的邊總和最小,那麼次小生成樹,要求邊集合的邊總和只比最小生成樹邊集合權值大.

總結性質

有至少乙個(嚴格)次小生成樹,和最小生成樹之間只有一條邊的差異。和真理只有一點差異,那就是出題人毒瘤

我們來粗略證明一下.(強行偽證)

我們知道最小生成樹,是由\(n-1\)條構成的.

那麼其他的\(m-n+1\)就是多餘邊.

假如說我們把一條多餘邊\((x,y,z)\),加入到了最小生成樹中,那麼一定會在\((x,y)\)之間的路徑上形成乙個環.

那麼這個環上面,最大的邊稱之為

\[val_1

\]次大的邊,稱之為

\[val_2

\]而且為了保證嚴格這個單調性質,我們必須

\[val_1>val_2 \quad 最大的邊一定大於次大的邊

\]接下來,我們就需要好好分析一下這條多餘邊了.

我們知道多餘邊,替換任何一條樹上的一條邊,都會使得最小生成樹,不再最小

為什麼?

因為最小生成樹上的每一條邊,一定是滿足貪心性質下的最小的邊.為什麼啊?相信你的直覺啊

這個證明,我們使用的克魯斯卡爾演算法,已經告訴我們為什麼.真相只有乙個,我懶了

總而言之,言而總之,我們現在知道了這條多餘邊的加入.,一定會產生非最小生成樹.

我們不妨令

\[ans=最小生成樹邊權之和

\]假如說我們將多餘邊,替換掉最大權值邊.

\[val_1 ==> z \\\

此時我們發現當前生成樹 w=ans+z-val_1 \\\\

w=最小生成邊權之和+加上多餘邊-最大權值邊

\]這一輪替換,我們可以認為這棵生成樹有潛力成為次小生成樹.

然後,我們發現,換一換次大邊,也是可以的.

我們將多餘邊,強行替換掉次大權值邊.

\[val_2 ==> z \\\\

此時當前生成樹 w=ans+z-val_2 \\\\

w=最小生成樹之和+加入多餘邊-次大權值邊

\]現在所有的候選生成樹都出來了,但是我們面臨乙個非常嚴重的問題.

我們如何快速計算,一條路徑上的最大邊,和次大邊.

動態規劃

我們可以當前需要知道的狀態,無非就是兩個.

一條路徑上的最大邊

一條路徑上的嚴格次大邊

所以說,我們不妨就按照倍增陣列的思路,去製造兩個新陣列.

最大邊陣列

嚴格次大邊陣列

\[f[x][k]=f[fa[x][k-1]][k-1]

\]這是我們非常熟悉的lca倍增陣列.

然後咱們現在其實,手上掌握的最有力的性質,就是最值性質.

我們假設一條路徑是由三段構造而成.

是三段,不是就三個點.

\[a=>c,c=>b,b=>a

\]我們發現

\[a=>b的最大值其實等於 \\\\

max(a=>c最大值,b=>c最大值)

\]這就是區間最值性質.

不過嚴格次大邊,就比較麻煩了,不慌,咱們慢慢畫圖來.

為了下面簡述方面,我們設定一下變數.

\[a=>c上最大邊權為val_ \quad 次大邊權為v_ \\\\

c=>b上最大邊權為val_ \quad 次大邊權為v_ \\\\

a=>b上最大邊權為val_ \quad 次大邊權為v_ \\\\

\]巧計一下,val字母多,所以是最大邊權,v字母少,所以是次大邊權.

我們分類討論一下,三種情況.

①第一段最大值=第二段最大值

\[val_=val_

\]我們發現兩段居然最大值一樣.

次大邊權就只能

\[v_=max(v_,v_)

\]②第一段最大值<第二段最大值.

那麼此時,次大邊權可以取第一段最大值.

因為此時總段的最大值,一定是第二段最大值.

\[val_=val_ \\\\

因此v_可以=val_

\]綜上所述,我們總結下來就是.

\[v_=max(val_,v_)

\]③第一段最大值>第二段最大值.

那麼此時,次大邊權是可以取第二段最大值.

因為此時總段的最大值,一定是第一段最大值.

\[val_=val_ \\\\

因此v_可以=val_

\]同樣,總結一下.

\[v_=max(val_,v_)

\]然後我們將\(a,b,c\)具體化一下.

a其實就是起始節點.

c其實就是a跳躍了\(2^\)格節點.

b其實就是a跳躍了\(2^\)格節點.

**解析

#include using namespace std;

#define inf 1e16

const int n=1e5+200;

const int m=6*1e5+300;

int head[m],edge[m],next[m],ver[m],tot,fa[m],n,m,father[n][32],deep[n];

long long dp[2][n][32],val1,val2,ans_max,ans;

struct node

s[m];

int cmp(node a,node b)

else}}

}}inline void update2(int x)

inline void update(int x, int t)

inline void lca(int x, int y)

if(x==y)

return;

for(int t=(int)log2(deep[x]); t>=0; t--)

}update(x,0),update(y,0);

}} g1;

int main()

g1.kruskal();

g1.bfs(1);

ans_max=inf;

for(int i=1; i<=m; i++)

}printf("%lld\n",ans_max);

return 0;

}

BJWC2010 嚴格次小生成樹

板子題 先kruskal得到最小生成樹,再列舉未加進生成樹中的邊i,該邊i和生成樹樹形成了乙個環,選擇這個環上最大的不等於i的權值的邊去掉就得到乙個新的樹,所有這樣得到的樹權值之和即為次小生成樹。求環上最大邊可以用倍增或者樹鏈剖分,由於最大邊可能和才加上去的邊相等,所以還要維護乙個次大邊 inclu...

P4180 嚴格次小生成樹 BJWC2010

題目鏈結 當時在暑假早就講了這道題了,只不過我現在才做了這道題。題解 我們要求次小生成樹的話,考慮先把最小生成樹求出來,因為如果我們用求最小生成樹的話,邊早已經從大到小排序好了,所以次小生成樹的就是替換最小生成樹上的一條邊所得。那麼考慮如何來替換那一條邊,要保證嚴格次小,那麼我們需要替換掉最小生成樹...

P4180 BJWC2010 嚴格次小生成樹

題目 最小生成樹都會吧?不會的戳這裡 接下來我們用lca求每一條非樹邊在樹上環的最大邊權和次大邊權,然後求乙個min s mx v,s mx2 v,mn 就可以了,注意如果mx v,第一項不比較.code include include include include include include...