题目链接:戳我
kruskal重构树。
具体可以参考我的简单学习笔记,或者更推荐的attack dalao的学习笔记
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 100010
using namespace std;
int n,m,k,cnt,t;
int fa[MAXN],head[MAXN],top[MAXN],dep[MAXN],val[MAXN],siz[MAXN],son[MAXN];
struct Edge{int u,v,dis;}edge[MAXN<<1];
struct Edge2{int nxt,to;}e[MAXN<<1];
inline bool cmp(struct Edge x,struct Edge y){return x.dis<y.dis;}
inline int find(int x){return fa[x]==x?x:find(fa[x]);}
inline void add(int from,int to)
{
e[++t].nxt=head[from],e[t].to=to,head[from]=t;
e[++t].nxt=head[to],e[t].to=from,head[to]=t;
}
inline void kruskal()
{
for(int i=1;i<=m;i++)
{
int u=edge[i].u,v=edge[i].v;
int a=find(u),b=find(v);
if(a==b) continue;
fa[a]=fa[b]=fa[++cnt]=cnt;
val[cnt]=edge[i].dis;
add(a,cnt),add(b,cnt);
}
}
inline void dfs1(int now,int pre)
{
fa[now]=pre;
dep[now]=dep[pre]+1;
siz[now]=1;
int maxx=-1;
for(int i=head[now];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==pre) continue;
dfs1(v,now);
siz[now]+=siz[v];
if(siz[v]>maxx) maxx=siz[v],son[now]=v;
}
}
inline void dfs2(int x,int topf)
{
top[x]=topf;
if(son[x]) dfs2(son[x],topf);
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==son[x]||v==fa[x]) continue;
dfs2(v,v);
}
}
inline 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]) return x;
else return y;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d%d",&n,&m,&k);
cnt=n;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].dis);
sort(&edge[1],&edge[m+1],cmp);
kruskal();
dfs1(cnt,0);
dfs2(cnt,cnt);
for(int i=1;i<=k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d
",val[lca(u,v)]);
}
return 0;
}
BZOJ50题纪念