lca 次小生成樹

2021-10-05 02:42:28 字數 1571 閱讀 8452

倍增法求lca:

求小資料次小生成樹:

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

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

輸入格式

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

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

輸出格式

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

資料範圍

n≤1e5,m≤3∗1e5

輸入樣例:

5 6 

1 2 1

1 3 2

2 4 3

3 5 4

3 4 3

4 5 6

輸出樣例:

11
思路:這題的n有1e5,所以就不能像以前一樣用dfs求沿路上的邊的最大值和次大值。這裡我用倍增法求lca,順便記錄沿路上的最大值和次大值。lca的複雜度就比較小,可以搞這題。求次小生成樹的原理還是和之前差不多的,就是判斷每條非樹邊能不能替代原本樹上的邊。

#include#define ll long long

#define inf 0x3f3f3f3f

using namespace std;

const int n=1e5+10,m=6e5+10;

struct ddq[m];

int n,m;

int first[n],ne[m],v[m],w[m],num_edge=0;

//f有兩個作用,乙個是在kruskal中建最小生成樹

//乙個是記錄每個人的直屬父親

int f[n],depth[n];

//dist1記錄從某個點跳2^i層的路徑中的最長邊

//dist1記錄從某個點跳2^i層的路徑中的次長邊

//st記錄從某個點跳2^i層所到達的點

int dist1[n][20],dist2[n][20],st[n][20];

//temp用於尋找lca中記錄下所有途經的邊,方便找到最大值次大值

int temp[m],cnt;

int qq[n];

bool cmp(dd x,dd y)

//找到lca,並記錄沿路的dist1和dist2

if(x!=y)

temp[++cnt]=dist1[x][0];

temp[++cnt]=dist1[y][0];

}//找一路上的最長邊和次長邊

int d1=-inf,d2=-inf;

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

//printf("%d %d %d\n",z,d1,d2);

//這條邊可以代替最長邊

if(z>d1)return z-d1;

//這條邊可以代替次長邊

if(z>d2)return z-d2;

//啥都代替不了

return inf;

}int main()

次小生成樹(lca)

題目描述 原題來自 beijing 2010 組隊賽 給定一張 n個點 m條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為 sum,嚴格次小生成樹就是指邊權之和大於 sum 的生成樹中最小的乙個。輸入格式 第一行包含兩個整數 n 和 m,表示無向圖的點數與邊數 接下來 m行,每行三個...

次小生成樹(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...