bzoj 3732 Network (kruskal重构树)
Posted uid001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3732 Network (kruskal重构树)相关的知识,希望对你有一定的参考价值。
大意: 无向图, 多组询问, 求从A点走到B点的所有路径中,最长的边最小值是多少.
kruskal重构树板子题, 最小值一定是最小生成树上的最长边, 转化为求kruskal重构树lca的点权.
#include <iostream> #include <algorithm> #include <cstdio> #include <queue> #define REP(i,a,n) for(int i=a;i<=n;++i) #define pb push_back using namespace std; const int N = 1e6+10; int n, m, k; int fa[N], son[N], dep[N], s[N]; int sz[N], top[N], val[N], vis[N]; struct _ int u,v,w; e[N]; vector<int> g[N]; void add(int u, int v) g[u].pb(v),g[v].pb(u); int Find(int x) return s[x]?s[x]=Find(s[x]):x; void dfs(int x, int f, int d) fa[x]=f,dep[x]=d,sz[x]=1; int mx = -1; for (int i=0;i<g[x].size();++i) int y = g[x][i]; if (y==f) continue; dfs(y,x,d+1),sz[x]+=sz[y]; if (sz[y]>mx) sz[y]=mx,son[x]=y; void dfs2(int x, int tf) top[x]=tf; if (son[x]) dfs2(son[x],tf); for (int i=0;i<g[x].size();++i) int y = g[x][i]; if (!top[y]) dfs2(y,y); int lca(int x, int y) while (top[x]!=top[y]) if (dep[top[x]]<dep[top[y]]) swap(x,y); x = fa[top[x]]; if (dep[x]>dep[y]) swap(x,y); return x; bool cmp(_ a, _ b) return a.w<b.w; int main() scanf("%d%d%d", &n, &m, &k); REP(i,1,m) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); sort(e+1,e+1+m,cmp); int tot = n; REP(i,1,m) int u=Find(e[i].u),v=Find(e[i].v); if (u!=v) s[u] = s[v] = ++tot; val[tot] = e[i].w; add(tot,u),add(tot,v); if (tot==2*n-1) break; dfs(tot,0,0),dfs2(tot,tot); while (k--) int x, y; scanf("%d%d", &x, &y); printf("%d\n", val[lca(x,y)]);
以上是关于bzoj 3732 Network (kruskal重构树)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 3732 Network Kruskal重构树+倍增LCA