• BZOJ 3732: Network(Kruskal重构树)


    传送门

    解题思路

      (Kruskal)重构树模板题,(Kruskal)重构树就是在建最小生成树加边的时候,不直接加边,而是新建一个点,而这个点的权值就是边权,这个新建的点作为原先点的父亲,并且把他们并起来。最终会得到一棵树,这个树有很多优秀的性质,首先它的叶结点都为原先的点,非叶结点为原先的边,还有从向下权值单调不减。那么这道题其实就算把(Kruskal)重构树建出来后两个点(LCA)的权值。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int N=30005;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    
    int n,m,q,f[N][20],head[N],to[N],nxt[N],w[N],tot;
    int F[N],cnt,num,dep[N];
    struct Edge{
    	int u,v,w;
    	friend bool operator<(const Edge A,const Edge B){
    		return A.w<B.w;
    	}
    }edge[N];
    
    int get(int x){
    	if(x==F[x]) return x;
    	return F[x]=get(F[x]);
    }
    
    inline void add(int bg,int ed){
    	to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
    }
    
    void dfs(int x,int FA){
    	f[x][0]=FA;
    	for(int i=1;i<=16;i++) 
    		f[x][i]=f[f[x][i-1]][i-1];
    	for(int i=head[x];i;i=nxt[i])
    		dep[to[i]]=dep[x]+1,dfs(to[i],x);
    }
    
    inline int lca(int x,int y){
    	if(dep[x]<dep[y]) swap(x,y);
    	for(int i=16;~i;i--)
    		if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    	if(x==y) return x;
    	for(int i=16;~i;i--)
    		if(f[x][i]!=f[y][i])
    			x=f[x][i],y=f[y][i];
    	return f[x][0];
    }
    
    int main(){
    	n=rd(),m=rd(),q=rd();num=n;
    	for(int i=1;i<=n;i++) F[i]=i;
    	for(int i=1;i<=m;i++)
    		edge[i].u=rd(),edge[i].v=rd(),edge[i].w=rd();
    	sort(edge+1,edge+1+m);int x,y;
    	for(int i=1;i<=m;i++){
    		x=get(edge[i].u),y=get(edge[i].v);
    		if(x==y) continue;tot++;
    		F[x]=y;w[++num]=edge[i].w;F[num]=num;
    		F[x]=num;F[y]=num;add(num,x);add(num,y);
    		if(tot==n-1) break;
    	}
    	dfs(num,0);
    	while(q--){
    		x=rd(),y=rd();
    		printf("%d
    ",w[lca(x,y)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    p2psearcher绿色版使用方法
    P2PSearcher云点播设置和使用技巧
    怎么看电脑有没有安装USB3.0驱动
    USB3.0驱动与2.0有什么区别
    win7 64位 安装java jdk1.8 ,修改配置环境变量
    jdk是什么?jdk1.8安装配置方法
    adb工具包究竟能帮我们做什么?
    web.xml中load-on-startup有和用处
    Spring Aop
    Struts2中的properties文件详解
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10274677.html
Copyright © 2020-2023  润新知