zoukankan      html  css  js  c++  java
  • bzoj3732

    转自hwzzyr的博客
    kruskal重构树
    借用网上找来的其他图片解释
    由于重构树中把原树的点权转换成为了新建节点的边权,这一过程是这样实现的。
    首先对边排序
    然后使用并查集辅助加边,每新建一条边时:
    新建节点indexindex(编号从n+1n+1开始)
    将原有两节点所在集合改为indexindex
    将原有节点与indexindex连边
    新建节点的权值为当前边的边权
    给一下简单的代码

    void Ex_Kruskal() {
        int ind=n,lim=n<<1; sort(e+1,e+1+m);
        for(int i=1;i<=lim;++i) f[i]=i;
        for(int i=1;i<=m;++i) {
            int fx=getfa(e[i].a),fy=getfa(e[i].b);
            if(fx!=fy) {
                f[fx]=f[fy]=++ind;
                val[ind]=e[i].w;
                add(ind,fx); add(ind,fy);
                if(ind==lim-1) break;
            }
        } return ;
    }
    

    代码复杂度很低,时间复杂度是优秀的O(nlog2n)

    例题bzoj3732

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=3e4+2;
    int n,m,q,cnt;
    int fa[N<<1],f[N<<1][20],dep[N<<1],val[N<<1],g[N<<1][2];
    int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
    struct data{
    	int u,v,w;
    	bool operator<(const data &a)const{return w<a.w;}
    }e[N<<1];
    inline int ask(int u,int v){
    	if(dep[u]<dep[v])swap(u,v);
    	int t=dep[u]-dep[v];
    	for(int i=0;i<20;i++)if(t&(1<<i))u=f[u][i];
    	for(int i=19;~i;i--)if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i];
    	if(u!=v)u=f[u][0];
    	return u;
    }
    inline void dfs(int u){
    	if(!g[u][0])return;
    	dep[g[u][0]]=dep[g[u][1]]=dep[u]+1;
    	dfs(g[u][0]),dfs(g[u][1]);
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&q),cnt=n;
    	for(int i=0;i<m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
    	sort(e,e+m);
    	for(int i=1;i<=n;i++)fa[i]=i,fa[i+n]=i+n;
    	for(int i=0;i<m;i++){
    		int u=e[i].u,v=e[i].v;
    		if(getfa(u)==getfa(v))continue;
    		g[++cnt][0]=fa[u],g[cnt][1]=fa[v];
    		fa[fa[u]]=fa[fa[v]]=f[fa[u]][0]=f[fa[v]][0]=cnt;
    		val[cnt]=e[i].w;
    	}
    	dfs(cnt);
    	for(int j=1;j<20;j++)
    		for(int i=1;i<=cnt;i++)f[i][j]=f[f[i][j-1]][j-1];
    	for(int x,y,i=0;i<q;i++){
    		scanf("%d%d",&x,&y);
    		printf("%d
    ",val[ask(x,y)]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ORA-01045: user XXZY lacks CREATE SESSION privilege; logon denied
    ORA-31626:作业不存在 ORA-31633:无法创建主表"XXX.SYS_IMPORT_FULL_05"
    HTTP 错误 401.3
    mysql 简单游标
    mysql 多重游标嵌套
    表单校验 “灰白字提示”
    Eclipse连接mysql数据库出现问题
    虚拟机无法使用桥接,没有未桥接网络适配器解决办法
    每周进度条(16)
    人月神话阅读笔记06
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9865550.html
Copyright © 2011-2022 走看看