bzoj3732: Network kruskal重构树

学了一波操作,学习网址:传送门

code:

#include<bits/stdc++.h>
using namespace std;
struct bia
{
	int x,y,v;
};
bia b[60010];
bool cmp(bia aa,bia bb){return aa.v<bb.v;}
struct one
{
	int y,next;
};
one e[60010];
int n,m,k,d[30010],p=0,tot,pp[30010][22],z[30010],fa[30010],len=0,lin[30010];
int getfather(int pp)
{if(pp==fa[pp])return pp;else return fa[pp]=getfather(fa[pp]);}
void dfs(int t,int dp)
{
	d[t]=dp;
	for(int i=lin[t];i;i=e[i].next)
	{
		pp[e[i].y][0]=t;
		dfs(e[i].y,dp+1);
	}
}
void insert(int x,int y)
{
	e[++len].next=lin[x];
	lin[x]=len;
	e[len].y=y;
}
void kruskal()
{
	for(int i=1;i<=n;i++)fa[i]=i;
	tot=0;p=n;
	int f1,f2,i=0;
	while(tot<n-1)
	{
		i++;
		f1=getfather(b[i].x);
		f2=getfather(b[i].y);
		if(f1!=f2)
		{
			tot++;p++;z[p]=b[i].v;
			fa[p]=p;fa[f1]=p;fa[f2]=p;
			insert(p,f1);
			insert(p,f2);
		}
	}
}
void init()
{
	for(int i=1;(1<<i)<=n;i++)
	{
		for(int j=1;j<=p;j++)
			pp[j][i]=pp[pp[j][i-1]][i-1];
	}
}
int lca(int xx,int yy)
{
	if(d[xx]>d[yy])swap(xx,yy);
	int ff=d[yy]-d[xx];
	for(int i=0;(1<<i)<=ff;i++)if(((1<<i)&ff))yy=pp[yy][i];
	if(xx==yy)return xx;
	else
	{
		for(int i=log(p);i>=0;i--)
		{
			if(pp[xx][i]!=pp[yy][i])
			{xx=pp[xx][i];yy=pp[yy][i];}
		}
		return pp[xx][0];
	}
}
int main()
{
	//freopen("xf.in","r",stdin);
	//freopen("xf.out","w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].v);
	sort(b+1,b+m+1,cmp);kruskal();
	dfs(p,0);
	init();
	for(int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		printf("%d\n",z[lca(x,y)]);
	}
	return 0;
}

  

posted @ 2018-03-20 16:50  mybing  阅读(196)  评论(2编辑  收藏  举报