zoukankan      html  css  js  c++  java
  • CF1184E2

    题目大意:
    给一个带权无向图。定义(E_{max} (c_i)) 是把第 (i) 条边的边权最大修改成多大,使得它可能出现在最小生成树中。求 (E_{max}(c_i)) ,保证最小生成树唯一。

    因为最小生成树唯一,所以还是有一个易证的结论:一条非树边的答案为对应最小生成树的链上最大值。

    #define B cout << "BreakPoint" << endl;
    #define O(x) cout << #x << " " << x << endl;
    #define O_(x) cout << #x << " " << x << " ";
    #define Msz(x) cout << "Sizeof " << #x << " " << sizeof(x)/1024/1024 << " MB" << endl;
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<set>
    #define LL long long
    const int inf = 1e9 + 9;
    const int N = 1e6 + 5;
    using namespace std;
    inline int read() {
    	int s = 0,w = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-')
    			w = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9') {
    		s = s * 10 + ch - '0';
    		ch = getchar();
    	}
    	return s * w;
    }
    int n,m;
    struct Tree{
    	struct edge { int to,nxt,w,id; }e[N << 1];int head[N],cnt;
    	void add(int u,int v,int w,int id) { e[++cnt].w = w,e[cnt].id = id,e[cnt].to = v,e[cnt].nxt = head[u];head[u] = cnt; }
    	void add_edge(int u,int v,int w,int id) { add(u,v,w,id),add(v,u,w,id); }
    	int dep[N],up[N],f[N][20],maxx[N][20];
    	void dfs(int u,int fa){
    		dep[u] = dep[fa] + 1,f[u][0] = fa;
    		for(int i = head[u];i;i = e[i].nxt){
    			int v = e[i].to;
    			if(v == fa) continue;
    			maxx[v][0] = e[i].w,up[v] = e[i].id;
    			dfs(v,u);
    		}
    	}
    	void init(){
    		dfs(1,0);
    		for(int j = 1;j < 20;j++)
    			for(int i = 1;i <= n;i++){
    				f[i][j] = f[f[i][j - 1]][j - 1];
    				maxx[i][j] = max(maxx[i][j - 1],maxx[f[i][j - 1]][j - 1]);
    			}
    	}
    	pair<int,int> LCA(int u,int v){
    		int ans = 0;
    		if(dep[u] < dep[v]) swap(u,v);
    		int h = dep[u] - dep[v];
    		for(int i = 0;i < 20;i++) if(h & (1 << i)) ans = max(ans,maxx[u][i]),u = f[u][i];
    		if(u == v) return make_pair(u,ans);
    		for(int i = 19;~i;i--) if(f[u][i] ^ f[v][i]) ans = max(ans,max(maxx[u][i],maxx[v][i])),u = f[u][i],v = f[v][i];
    		return make_pair(f[u][0],max(ans,max(maxx[u][0],maxx[v][0])));
    	}
    }T;
    struct edge{
    	int u,v,w,id;
    	friend bool operator < (edge a,edge b) { return a.w < b.w; }
    }e[N];
    bool vis[N];
    int fa[N],ans[N];
    int find(int u) { return fa[u] == u ? u : fa[u] = find(fa[u]); }
    int main(){
    	n = read(),m = read();
    	for(int i = 1;i <= m;i++) e[i].u = read(),e[i].v = read(),e[i].w = read(),e[i].id = i;
    	sort(e + 1,e + 1 + m);
    	for(int i = 1;i <= n;i++) fa[i] = i;
    	for(int i = 1;i <= m;i++){
    		int x = find(e[i].u),y = find(e[i].v);
    		if(x ^ y){
    			fa[x] = y;
    			T.add_edge(e[i].u,e[i].v,e[i].w,e[i].id);
    			vis[i] = 1;
    		}
    	}
    	T.init();
    	for(int i = 1;i <= m;i++) 
    		if(!vis[i]){
    			auto w = T.LCA(e[i].u,e[i].v);
    			ans[e[i].id] = w.second;
    		}
    	for(int i = 1;i <= m;i++) if(ans[i]) printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    mysql数据库——特殊sql语句整理之修改表结构
    mysql数据库引擎——MyISAM,InnoDB
    Golang程序性能分析
    Docker基本操作
    go module
    Docker基础原理
    基于zookeeper或redis实现分布式锁
    漫谈微服务
    快速排序
    设计模式泛谈
  • 原文地址:https://www.cnblogs.com/excellent-zzy/p/12548485.html
Copyright © 2011-2022 走看看