zoukankan      html  css  js  c++  java
  • CF609E. Minimum spanning tree for each edge

    题解:随便构造一颗最小生成树 然后对于其他不在树上的边  考虑到 删除这条链上的最大值在把这条边加上去 能得到这条边所在的最小生成树 可以LCT维护 但是明显这个题是静态的树就没必要LCT 当然我觉得最优的是树剖以后ST nlogn的的复杂度 也可以树剖+线段树nlog^2的复杂度

    #include <bits/stdc++.h>
    const int MAXN=2e5+10;
    #define ll long long
    using namespace std;
    ll read(){  
        ll x=0,f=1;char ch=getchar();  
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}  
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();  
        return f*x;  
    }
    typedef struct Edge{
    	int u,v,vul,id;
    	friend bool operator<(Edge aa,Edge bb){
    		return aa.vul<bb.vul;
    	}
    }Edge;
    Edge ed[MAXN];int mu[MAXN],ma[21];
    int f[MAXN];ll ans[MAXN];
    int n,m;
    int find1(int x){
    	if(f[x]==x)return x;
    	return f[x]=find1(f[x]);
    }
    vector<Edge>v1;
    vector<Edge>v2;
    vector<pair<int,int> >vec[MAXN];
    int fa[MAXN],num[MAXN],dep[MAXN],son[MAXN];
    int dp[MAXN][21],vul[MAXN];
    void dfs(int v,int pre,int deep){
    	fa[v]=pre;num[v]=1;dep[v]=deep+1;
    	for(int i=0;i<vec[v].size();i++){
    		if(vec[v][i].first!=pre){
    			//F[vec[v][i].first][0]=pre;
    			vul[vec[v][i].first]=vec[v][i].second;
    			dfs(vec[v][i].first,v,deep+1);
    			num[v]+=num[vec[v][i].first];
    			if(son[v]==-1||num[vec[v][i].first]>num[son[v]])son[v]=vec[v][i].first;
    		}
    	}
    }
    int tp[MAXN],p[MAXN],fp[MAXN],cnt;
    void dfs1(int v,int td){
    	tp[v]=td;p[v]=++cnt;fp[p[v]]=v;
    	if(son[v]!=-1)dfs1(son[v],td);
    	for(int i=0;i<vec[v].size();i++){
    		if(vec[v][i].first!=fa[v]&&vec[v][i].first!=son[v])dfs1(vec[v][i].first,vec[v][i].first);
    	}
    }
    void st(){
    	for(int i=1;i<=n;i++)dp[i][0]=vul[fp[i]];
    	for(int j=1;ma[j]<=n;j++){
    		for(int i=1;i<=n;i++){
    			dp[i][j]=max(dp[i][j-1],dp[i+ma[j-1]][j-1]);
    		}
    	}
    }
    int rmq(int l,int r){
    	int k=mu[r-l+1];
    	return max(dp[l][k],dp[r-ma[k]+1][k]);
    }
    int Lca(int u,int v){
    	int maxx=-1;
    	int uu=tp[u];int vv=tp[v];
    	while(uu!=vv){
    		if(dep[uu]<dep[vv])swap(uu,vv),swap(u,v);
    		maxx=max(maxx,rmq(p[uu],p[u]));
    		u=fa[uu];uu=tp[u];
    	}
    	if(dep[u]>dep[v])swap(u,v);
    	if(u!=v)maxx=max(maxx,rmq(p[son[u]],p[v]));
    	return maxx;
    }
    int main(){
    	ma[0]=1;
    	for(int i=1;i<21;i++)ma[i]=ma[i-1]<<1;
    	mu[0]=-1;
    	for(int i=1;i<MAXN;i++){
        if((i&(i-1))==0)mu[i]=mu[i-1]+1;
        else mu[i]=mu[i-1];
        }
    	n=read();m=read();
    	for(int i=1;i<=n;i++)f[i]=i,son[i]=-1;
    	for(int i=1;i<=m;i++)ed[i].id=i,ed[i].u=read(),ed[i].v=read(),ed[i].vul=read();
    	sort(ed+1,ed+m+1);ll sum=0;
    	for(int i=1;i<=m;i++){
    		int t1=find1(ed[i].u);int t2=find1(ed[i].v);
    		if(t1!=t2){
    			f[t1]=t2;sum+=ed[i].vul;
    			v2.push_back(ed[i]);
    			vec[ed[i].u].push_back(make_pair(ed[i].v,ed[i].vul));
    			vec[ed[i].v].push_back(make_pair(ed[i].u,ed[i].vul));
    		}
    		else v1.push_back(ed[i]);
    	}
    	dfs(1,0,0);dfs1(1,1);
    	st();
    	for(int i=0;i<v2.size();i++)ans[v2[i].id]=sum;
    	for(int i=0;i<v1.size();i++){
    		int key=Lca(v1[i].u,v1[i].v);
    	//	cout<<key<<endl;
    		ans[v1[i].id]=sum-key+v1[i].vul;
    	}
    	for(int i=1;i<=m;i++)printf("%lld
    ",ans[i]);
    	return 0;
    }
    

      

                  E. Minimum spanning tree for each edge
                      time limit per test
                      2 seconds
                      memory limit per test
                      256 megabytes
    input
    standard input
    output
    standard output

    Connected undirected weighted graph without self-loops and multiple edges is given. Graph contains n vertices and m edges.

    For each edge (u, v) find the minimal possible weight of the spanning tree that contains the edge (u, v).

    The weight of the spanning tree is the sum of weights of all edges included in spanning tree.

    Input

    First line contains two integers n and m (1 ≤ n ≤ 2·105, n - 1 ≤ m ≤ 2·105) — the number of vertices and edges in graph.

    Each of the next m lines contains three integers ui, vi, wi (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ wi ≤ 109) — the endpoints of the i-th edge and its weight.

    Output

    Print m lines. i-th line should contain the minimal possible weight of the spanning tree that contains i-th edge.

    The edges are numbered from 1 to m in order of their appearing in input.

    Examples
    input
    Copy
    5 7
    1 2 3
    1 3 1
    1 4 5
    2 3 2
    2 5 3
    3 4 2
    4 5 4
    output
    Copy
    9
    8
    11
    8
    8
    8
    9
  • 相关阅读:
    C# 把一个文件夹下所有文件复制到另一个文件夹下 把一个文件夹下所有文件删除(转)
    【总结整理】webGIS学习thinkGIS(四)WebGIS中通过行列号来换算出多种瓦片的URL 之离线地
    ARCGIS空间叠加分析(转)
    ARCGIS中怎么去除重复的面?(转)
    关于写作赚钱(转)
    【总结整理】WebGIS学习-thinkGIS(三):关于影像金字塔、瓦片行列号、分辨率resolution
    【总结整理】WebGIS学习-thinkGIS(地理常识):
    【总结整理】WebGIS学习-thinkGIS(二):关于level,比例尺scale,分辨率resolution
    【总结整理】AMAP学习AMAP.PlaceSearch()
    logging、hashlib、collections模块
  • 原文地址:https://www.cnblogs.com/wang9897/p/9195843.html
Copyright © 2011-2022 走看看