codeforces 609E Minimum spanning tree for each edge
2 seconds
256 megabytes
standard input
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.
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.
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.
5 7
1 2 3
1 3 1
1 4 5
2 3 2
2 5 3
3 4 2
4 5 4
9
8
11
8
8
8
9
保证某条边e存在的MST就是普通Kruskal把e优先到了最前面。
先求一遍MST,如果e不再MST上,是因为形成了环,把环上除了e的最大权边去掉就好了。
(以前的LCA:用ST来RMQ,查询O(1)
(向祖先结点倍增其实和ST差不多,查询O(logn),维护信息灵活
(一开始想的是树剖,复杂度稍高
#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int N = 2e5+, M = N*; int pa[N], rak[N];
int fd(int x){ return pa[x] ? pa[x] = fd(pa[x]) : x; }
bool unite(int x,int y)
{
int a = fd(x), b = fd(y);
if(a == b) return false;
if(rak[a] < rak[b]){
pa[a] = b;
}
else {
pa[b] = a;
if(rak[a] == rak[b]) rak[a]++;
}
return true;
} int fro[N], to[N], we[N]; int hd[N];
int nx[M], ver[M], wei[M];
int ec; void add_e(int u,int v,int w)
{
ver[++ec] = v;
wei[ec] = w;
nx[ec] = hd[u];
hd[u] = ec;
} int n, m;
int *cmp_c;
bool cmp_id(int i,int j){ return cmp_c[i] < cmp_c[j]; } int r[N];
ll kruskal()
{
ll re = ;
int i,j;
for(i = ; i <= m; i++) r[i] = i;
cmp_c = we;
sort(r+, r + + m, cmp_id);
//ec = 0;
for(i = ; i <= m; i++){
j = r[i];
if(unite(fro[j],to[j])){
add_e(fro[j],to[j],we[j]);
add_e(to[j],fro[j],we[j]);
re += we[j];
we[j] = ;
}
}
return re;
} const int LOG = ; int fa[N][LOG], mx[N][LOG];
int dep[N]; void dfs(int u,int f = ,int fw = ,int d = )
{
fa[u][] = f;
mx[u][] = fw;
dep[u] = d;
for(int i = hd[u]; i; i = nx[i]) {
int v = ver[i];
if(v == f) continue;
dfs(v,u,wei[i],d+);
}
} int lg; int queryMx(int u,int v)
{
int re = , i;
if(dep[u] < dep[v]) swap(u,v);
for(i = lg; i >= ; i--) if(dep[u] - (<<i) >= dep[v]){
re = max(re,mx[u][i]);
u = fa[u][i];
}
if(u == v) return re;
for(i = lg; i >= ; i--) if(fa[u][i] != fa[v][i]){
re = max(re,max(mx[u][i],mx[v][i]));
u = fa[u][i];
v = fa[v][i];
}
return max(re,max(mx[u][],mx[v][]));
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
//cout<<log2(N);
scanf("%d%d",&n,&m);
int i,j;
for(i = ; i <= m; i++){
scanf("%d%d%d",fro+i,to+i,we+i);
}
ll mst = kruskal(); dfs();
lg = ceil(log2(n));
for(j = ; j <= lg; j++){
for(i = ; i <= n; i++) if(fa[i][j-]){
fa[i][j] = fa[fa[i][j-]][j-];
mx[i][j] = max(mx[i][j-],mx[fa[i][j-]][j-]);
}
}
for(i = ; i <= m; i++) {
printf("%I64d\n",we[i]?mst + we[i] - queryMx(fro[i],to[i]):mst);
}
return ;
}
codeforces 609E Minimum spanning tree for each edge的更多相关文章
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- codeforces 609E. Minimum spanning tree for each edge 树链剖分
题目链接 给一个n个节点m条边的树, 每条边有权值, 输出m个数, 每个数代表包含这条边的最小生成树的值. 先将最小生成树求出来, 把树边都标记. 然后对标记的边的两个端点, 我们add(u, v), ...
- Educational Codeforces Round 3 E (609E) Minimum spanning tree for each edge
题意:一个无向图联通中,求包含每条边的最小生成树的值(无自环,无重边) 分析:求出这个图的最小生成树,用最小生成树上的边建图 对于每条边,不外乎两种情况 1:该边就是最小生成树上的边,那么答案显然 2 ...
- cf 609E.Minimum spanning tree for each edge
最小生成树,lca(树链剖分(太难搞,不会写)) 问存在这条边的最小生成树,2种情况.1.这条边在原始最小生成树上.2.加上这条半形成一个环(加上),那么就找原来这条边2端点间的最大边就好(减去).( ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge 树上倍增
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
随机推荐
- PIE SDK图片元素的绘制
1. 功能简介 在数据的处理中会用到图片元素的绘制,利用IPictureElement图片元素接口进行绘制,目前PIE SDK支持IPictureElement元素接口的绘制,下面对图片元素的绘制进行 ...
- PIE SDK图像旋转
1.算法功能简介 图像旋转可使图像以中心点为轴沿特定方向旋转指定的角度. PIESDK支持算法功能的执行,下面对图像旋转算法功能进行介绍. 2.算法功能实现说明 2.1 实现步骤 第一步 算法参数设置 ...
- (Frontend Newbie)Web三要素(三)
上一篇简单介绍了Web三要素中的层叠样式表,本篇主要介绍三要素中最后一个,也是最难掌握的一个-----JavaScript. JavaScript 老规矩不能破,先简要交代 JavaScript 的历 ...
- 安卓获取输入法高度与ViewTreeObserver讲解
目录 安卓获取输入法高度 前言 清单 开始 ViewTreeObserver讲解 获取输入法高度原理 思路 实现 关于ViewTreeObserver 定义 继承 摘要 获取View高度的三种方法 源 ...
- nyoj 220——推桌子——————【贪心】
推桌子 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 The famous ACM (Advanced Computer Maker) Company has re ...
- nyoj 1208——水题系列——————【dp】
水题系列 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 给你一个有向图,每条边都有一定的权值,现在让你从图中的任意一点出发,每次走的边的权值必须必上一次的权 ...
- js 中移动元素的方法
2017-12-13 19:59:24 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- js 省份城市二级动态联动的例子
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 【XShell】xshell 中“快速命令集”的使用
突然看到朋友的xshell比我多一个按钮,且一点,哈哈哈 ,实现了很炫酷的功能,耐不住好奇,问了一句,原来是快速命令集! 1.选择快速命令集(两种方法a&b) a:文件 > 属性 > ...
- [转]How to use IHttpContextAccessor in static class to set cookies
本文转自:http://stackoverflow.com/questions/37329354/how-to-use-ihttpcontextaccessor-in-static-class-to- ...