BZOJ 3732: Network Kruskal 重构树

模板题,练练手~

Code: 

#include <cstdio> 
#include <algorithm>         
#define N 80000    
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;    
namespace tree { 
	int hd[N],to[N],nex[N],edges; 
	int fa[N],top[N],siz[N],dep[N],son[N]; 
	void addedge(int u,int v) {
		nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
	} 
	void dfs1(int u,int ff) {
		fa[u]=ff,siz[u]=1,dep[u]=dep[ff]+1; 
		for(int i=hd[u];i;i=nex[i]) 
			if(to[i]!=ff) {
				dfs1(to[i],u),siz[u]+=siz[to[i]]; 
				if(siz[to[i]]>siz[son[u]]) son[u]=to[i];    
			}
	}  
	void dfs2(int u,int tp) {
		top[u]=tp; 
		if(son[u]) dfs2(son[u],tp); 
		for(int i=hd[u];i;i=nex[i]) 
			if(to[i]!=son[u]&&to[i]!=fa[u]) 
				dfs2(to[i],to[i]); 
	} 
	int LCA(int x,int y) {
		while(top[x]!=top[y]) 
			dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; 
		return dep[x]<dep[y]?x:y;   
	}
}; 
struct Edge {
	int u,v,c; 
}e[N]; 
bool cmp(Edge a,Edge b) {
	return a.c<b.c;     
}
int p[N],maxv[N],n,m,k,tot;        
int find(int x) {
	return p[x]==x?x:p[x]=find(p[x]); 
}
int main() { 
	int i,j; 
	// setIO("input");    
	scanf("%d%d%d",&n,&m,&k);        
	for(i=1;i<=m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c); 
	for(i=1;i<=n;++i) p[i]=i;   
	sort(e+1,e+1+m,cmp);       
    tot=n; 
	for(i=1;i<=m;++i) {
		int u=e[i].u,v=e[i].v,c=e[i].c;     
		int x=find(u),y=find(v);    
		if(x!=y) { 
			++tot; 
			p[tot]=tot; 
			maxv[tot]=c;          
			p[x]=p[y]=tot;  
			tree::addedge(tot,x),tree::addedge(tot,y);                 
		}
	}   
	tree::dfs1(tot,0); 
	tree::dfs2(tot,tot); 
	for(i=1;i<=k;++i) {
		int x,y; 
		scanf("%d%d",&x,&y); 
		printf("%d\n",maxv[tree::LCA(x,y)]);   
	} 
	return 0;  
}

  

posted @ 2019-08-29 08:18  EM-LGH  阅读(124)  评论(0编辑  收藏  举报