蓝桥杯真题讲解:网络稳定性(Kruskal重构树+LCA)
一、视频讲解
二、正解代码
cpp
//kruskal重构树 + lca
#include<bits/stdc++.h>
#define endl "\n"
#define deb(x) cout << #x << " = " << x << '\n';
#define INF 0x3f3f3f3f
using namespace std;
const int N = 2e5 + 10;
const int M = 3e5 + 10;
int n, m, q;
struct edge{
int x, y, w;
}e[M];
vector<int>g[N];
int p[N];
int val[N];//重构树节点的权值。
int find(int x){
if(x != p[x])p[x] = find(p[x]);
return p[x];
}
void kruskal(){
for(int i = 1; i <= n * 2; i ++){
p[i] = i;
}
sort(e, e + m, [&](edge x, edge y){return x. w > y.w;});
int id = n;
for(int i = 0; i < m; i ++){
int x = e[i].x, y = e[i].y, w = e[i].w;
int px = find(x), py = find(y);
if(py == px)continue;
id ++;
p[px] = id, p[py] = id;
g[id].push_back(py);
g[id].push_back(px);
val[id] = w;
}
}
int dep[N], fa[N], siz[N];
int top[N], hs[N];
void dfs1(int u, int f){
dep[u] = dep[f] + 1;
siz[u] = 1;
fa[u] = f;
for(auto s: g[u]){
if(s == f)continue;
dfs1(s, u);
siz[u] += siz[s];
if(siz[s] > siz[hs[u]])
hs[u] = s;
}
}
void dfs2(int u, int t) {
top[u] = t;
if(!hs[u])return;
dfs2(hs[u], t);
for(auto s: g[u]){
if(s == fa[u] || s == hs[u])continue;
dfs2(s, s);
}
}
int lca(int u, int v){
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]])
swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
void solve()
{
cin >> n >> m >> q;
for(int i = 0; i < m; i ++){
cin >> e[i].x >> e[i].y >> e[i].w;
}
kruskal();
for(int i = 1; i <= 2 * n; i ++){
if(p[i] == i){
//该连通块中lca的预处理
dfs1(i, 0);
dfs2(i, i);
}
}
while(q --){
int a, b; cin >> a >> b;
if(find(a) != find(b)){
cout << -1 << endl;
continue;
}
cout << val[lca(a, b)] << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
//cin >> t;
while(t--)
solve();
}