zoukankan      html  css  js  c++  java
  • [BeiJing2010组队]次小生成树 Tree

    1977: [BeiJing2010组队]次小生成树 Tree

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 5168  Solved: 1668
    [Submit][Status][Discuss]

    Description

    小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足:(value(e) 表示边 e的权值) 这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。

    Input

    第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。

    Output

    包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)

    Sample Input

    5 6
    1 2 1
    1 3 2
    2 4 3
    3 5 4
    3 4 3
    4 5 6

    Sample Output

    11

    HINT

    数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。

    Source

    [Submit][Status][Discuss]
    
    HOME Back

    题解

    先求出最小生成树,要严格次小
    枚举每一条非树边找俩顶点树链上的最大边(如果最大边相同与非树边边权相同则找次大边)然后更新最小增量
    最大边和次大边可以通过树上倍增求出

    复杂度是最小生成树(mlog m),枚举边乱搞(mlog n),所以是(mlog nm)

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    
    co int N=1e5+1,M=3e5+1,INF=0x3f3f3f3f;
    int n,m,t,fa[N],d[N],f[N][18];
    struct edge{
    	int x,y,z,k;
    	bool operator<(co edge&e)co {return z<e.z;}
    }p[M];
    int g[N][18][2];
    ll sum,ans=1e18;
    vector<pair<int,int> > e[N];
    int get(int x) {return fa[x]==x?x:fa[x]=get(fa[x]);}
    void kruskal(){
    	sort(p+1,p+m+1);
    	for(int i=1;i<=n;++i) fa[i]=i;
    	for(int i=1,x,y;i<=m;++i){
    		x=get(p[i].x),y=get(p[i].y);
    		if(x==y) continue;
    		fa[x]=y,sum+=p[i].z,p[i].k=1;
    	}
    }
    void dfs(int x){
    	for(int i=0,y;i<e[x].size();++i){
    		if(d[y=e[x][i].first]) continue;
    		d[y]=d[x]+1;
    		f[y][0]=x;
    		g[y][0][0]=e[x][i].second;
    		g[y][0][1]=-INF;
    		for(int j=1;j<=t;++j){
    			f[y][j]=f[f[y][j-1]][j-1];
    			g[y][j][0]=max(g[y][j-1][0],g[f[y][j-1]][j-1][0]);
    			if(g[y][j-1][0]==g[f[y][j-1]][j-1][0])
    				g[y][j][1]=max(g[y][j-1][1],g[f[y][j-1]][j-1][1]);
    			else if(g[y][j-1][0]<g[f[y][j-1]][j-1][0])
    				g[y][j][1]=max(g[y][j-1][0],g[f[y][j-1]][j-1][1]);
    			else g[y][j][1]=max(g[y][j-1][1],g[f[y][j-1]][j-1][0]);
    		}
    		dfs(y);
    	}
    }
    void lca(int x,int y,int&val1,int&val2){
    	if(d[x]>d[y]) swap(x,y);
    	for(int i=t;i>=0;--i)if(d[f[y][i]]>=d[x]){
    		if(val1>g[y][i][0]) val2=max(val2,g[y][i][0]);
    		else{
    			val1=g[y][i][0];
    			val2=max(val2,g[y][i][1]);
    		}
    		y=f[y][i];
    	}
    	if(x==y) return;
    	for(int i=t;i>=0;--i)if(f[x][i]!=f[y][i]){
    		val1=max(val1,max(g[x][i][0],g[y][i][0]));
    		val2=max(val2,g[x][i][0]!=val1?g[x][i][0]:g[x][i][1]);
    		val2=max(val2,g[y][i][0]!=val1?g[y][i][0]:g[y][i][1]);
    		x=f[x][i],y=f[y][i];
    	}
    	val1=max(val1,max(g[x][0][0],g[y][0][0]));
    	val2=max(val2,g[x][0][0]!=val1?g[x][0][0]:g[x][0][1]);
    	val2=max(val2,g[y][0][0]!=val1?g[y][0][0]:g[y][0][1]);
    }
    int main(){
    	read(n),read(m);
    	for(int i=1;i<=m;++i) read(p[i].x),read(p[i].y),read(p[i].z);
    	kruskal();
    	for(int i=1;i<=m;++i)if(p[i].k)
    		e[p[i].x].push_back(make_pair(p[i].y,p[i].z)),e[p[i].y].push_back(make_pair(p[i].x,p[i].z));
    	t=log(n)/log(2)+1;
    	d[1]=1;
    	for(int i=0;i<=t;++i) g[1][i][0]=g[1][i][1]=-INF;
    	dfs(1);
    	for(int i=1;i<=m;++i)if(!p[i].k){
    		int val1=-INF,val2=-INF;
    		lca(p[i].x,p[i].y,val1,val2);
    		if(p[i].z>val1) ans=min(ans,sum-val1+p[i].z);
    		else ans=min(ans,sum-val2+p[i].z);
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    用迁移学习创造的通用语言模型ULMFiT,达到了文本分类的最佳水平
    论文分享|《Universal Language Model Fine-tuning for Text Classificatio》
    tesnorflow实现N个epoch训练数据读取的办法
    理解TensorFlow的Queue
    tensorflow基本操作介绍
    前端框架 Vue 初探
    LeetCode 292 Nim Game(Nim游戏)
    设计模式有感
    说说翻转的数据结构课
    java 中xml转换为json对象
  • 原文地址:https://www.cnblogs.com/autoint/p/10935173.html
Copyright © 2011-2022 走看看