zoukankan      html  css  js  c++  java
  • BZOJ 3732 Network

    题解:求最大生成树,则边一定在最大生成树上,证明用Kluscal

    然后就是倍增

    TMD我竟然建树写错了,MDMDMDMDMDMD

    为什么一开始没想到QWQ

    总结:不要往难处想

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=30009;
    
    int n,m,T;
    
    struct Edge{
    	int u,v,d;
    }edges[maxn];
    bool cmp(const Edge &rhs1,const Edge &rhs2){
    	return rhs1.d<rhs2.d;
    }
    int father[maxn];
    int Getf(int x){
    	if(father[x]==x)return x;
    	return father[x]=Getf(father[x]);
    }
    void Unionn(int x,int y){
    	int fx=Getf(x);
    	int fy=Getf(y);
    	if(fx!=fy)father[fx]=fy;
    }
    
    int cntedge;
    int head[maxn];
    int to[maxn<<1],nex[maxn<<1],dist[maxn];
    void Addedge(int x,int y,int z){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	dist[cntedge]=z;
    	head[x]=cntedge;
    }
    
    int f[maxn][20],g[maxn][20],dep[maxn];
    void Dfs(int now,int fa){
    	dep[now]=dep[fa]+1;
    	for(int i=head[now];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		f[to[i]][0]=now;
    		g[to[i]][0]=dist[i];
    		Dfs(to[i],now);
    	}
    }
    void LCAinit(){
    	for(int j=1;j<=19;++j){
    		for(int i=1;i<=n;++i){
    			f[i][j]=f[f[i][j-1]][j-1];
    			g[i][j]=max(g[i][j-1],g[f[i][j-1]][j-1]);
    		}
    	}
    }
    int GetMaxd(int u,int v){
    	int ret=0;
    	if(dep[u]<dep[v])swap(u,v);
    	for(int j=19;j>=0;--j){
    		if(dep[f[u][j]]>=dep[v]){
    			ret=max(ret,g[u][j]);
    			u=f[u][j];
    		}
    	}
    	if(u==v)return ret;
    	for(int j=19;j>=0;--j){
    		if(f[u][j]!=f[v][j]){
    			ret=max(ret,max(g[u][j],g[v][j]));
    			u=f[u][j];v=f[v][j];
    		}
    	}
    	return max(ret,max(g[u][0],g[v][0]));
    }
    
    int main(){
    	scanf("%d%d%d",&n,&m,&T);
    	for(int i=1;i<=m;++i)scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].d);
    	sort(edges+1,edges+1+m,cmp);
    	for(int i=1;i<=n;++i)father[i]=i;
    	for(int i=1;i<=m;++i){
    		int u=edges[i].u;
    		int v=edges[i].v;
    		int d=edges[i].d;
    		if(Getf(u)==Getf(v))continue;
    		Unionn(u,v);
    		Addedge(u,v,d);
    		Addedge(v,u,d);
    	}
    	
    	Dfs(1,0);
    	LCAinit();
    //	
    //	for(int i=1;i<=n;++i){
    //		printf("%d %d
    ",f[i][0],g[i][0]);
    //	}
    	
    	while(T--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		printf("%d
    ",GetMaxd(x,y));
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    Android 通过ViewFlipper实现广告轮播功能并可以通过手势滑动进行广告切换
    [C#][DevPress]自定义数据分页控件
    [C#][SQLLITE]一个数据分页技巧
    [C#]用SharpZipLib压缩多个文件
    [C#][DevPress]省市县乡嵌套查询
    [C#][DevPress]事件委托的使用
    [C#]Excel操作类
    [C#][DevPress]手动添加控件中的子控件或者结构
    [C#]XML操作类
    [C#]把DataTable转换成泛型实体List
  • 原文地址:https://www.cnblogs.com/zzyer/p/8475976.html
Copyright © 2011-2022 走看看