題目描述
原題來自: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
#includeconstint 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...