次小生成樹(lca)

2022-05-25 03:15:11 字數 1772 閱讀 7867

題目描述

原題來自:beijing 2010 組隊賽

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

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

輸入格式

第一行包含兩個整數 n 和 m,表示無向圖的點數與邊數;

接下來 m行,每行三個數 x,y,z表示點 x和點 y之間有一條邊,邊的權值為 z。

輸出格式

包含一行,僅乙個數,表示嚴格次小生成樹的邊權和。

資料保證必定存在嚴格次小生成樹。

樣例樣例輸入

5 6 

1 2 1

1 3 2

2 4 3

3 5 4

3 4 3

4 5 6

樣例輸出

11

#includeconst

int maxn=100005,maxm=300005

;using

namespace

std;

intn,m,n;

struct

ea[maxm*2

];bool

mw(e a,e b)

struct

edgeedge[maxm*2

];int head[maxn],num=0

;int

fa[maxn],find();

long

long ans,mn=100000000000

;int f[maxn][25

],dep[maxn];

long

long d1[maxn][25],d2[maxn][25

];inline

void add(int u,int v,long

long

val)

inline

int find(int

a)inline

void

grow()

}return;}

inline

void dfs(int

u) }

for(register int i=head[u];i;i=edge[i].next)

return;}

inline

int lca(int a,int

b)

if(a==b)return

a;

for(register int i=n;i>=0;i--)

}return f[a][0];}

inline

void try(int u,int father,long

long

val)

else

u=f[u][i];//

寫的好神奇

} }

if(mx1!=val)

}else

}return;}

inline

void

choose()

return;}

intmain()

grow();

n=floor(log(n+0.0)/log(2.0

)); dfs(1);

choose();

printf(

"%lld

",ans+mn);

return0;

}

lca 次小生成樹

倍增法求lca 求小資料次小生成樹 給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊...

次小生成樹(LCA )

給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。輸出格式 包含一行,僅乙...

次小生成樹 倍增 LCA

給乙個n個點m條邊 n 100000,m 300000 的無向圖,求它的嚴格次小生成樹。資料範圍很大,o n 2 的演算法顯然是不行的。由於最小生成樹是一棵樹,求任意兩點路徑上的最大 次大邊就成為了經典的lca問題。因此,我們得到了下面的演算法 1 把邊按權值從小到大排序,時間複雜度為o mlogm...