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.

Sample test(s)
input
5 7
1 2 3
1 3 1
1 4 5
2 3 2
2 5 3
3 4 2
4 5 4
output
9
8
11
8
8
8
9

题意:给出一个图,问每一条边如果要在一个生成树当中,那这个生成树最小是多少。

分析:先找出一个最小生成树。

想像一下,加入一条边,会对这个生成树造成什么影响。

形成了一个环,然后最优情况,肯定要拿掉除他之外最大的一条边。

问题就变成了,在最小生成树上查询两点之间的边的最大值。

 /**
Create By yzx - stupidboy
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <ctime>
#include <iomanip>
using namespace std;
typedef long long LL;
typedef double DB;
#define MIT (2147483647)
#define INF (1000000001)
#define MLL (1000000000000000001LL)
#define sz(x) ((int) (x).size())
#define clr(x, y) memset(x, y, sizeof(x))
#define puf push_front
#define pub push_back
#define pof pop_front
#define pob pop_back
#define mk make_pair inline int Getint()
{
int Ret = ;
char Ch = ' ';
bool Flag = ;
while(!(Ch >= '' && Ch <= ''))
{
if(Ch == '-') Flag ^= ;
Ch = getchar();
}
while(Ch >= '' && Ch <= '')
{
Ret = Ret * + Ch - '';
Ch = getchar();
}
return Flag ? -Ret : Ret;
} const int N = , M = ;
int n, m;
struct EdgeType
{
int u, v, value, index;
LL ans;
inline bool operator <(const EdgeType &t) const
{
return value < t.value;
} inline void Read()
{
u = Getint();
v = Getint();
value = Getint();
}
} edge[N];
int fa[N], favalue[N];
int first[N], to[N * ], value[N * ], next[N * ], tot;
int up[N][M], depth[N], maxcnt[N][M];
LL ans; inline void Input()
{
n = Getint();
m = Getint();
for(int i = ; i <= m; i++)
{
edge[i].Read();
edge[i].index = i;
}
} inline int Find(int x)
{
static int path[N], len;
for(len = ; x != fa[x]; x = fa[x])
path[++len] = x;
for(int i = ; i <= len; i++) fa[path[i]] = x;
return x;
} inline void Insert(int u, int v, int val)
{
tot++;
to[tot] = v, value[tot] = val, next[tot] = first[u];
first[u] = tot;
} inline void Bfs()
{
static int que[N], head, tail;
for(int i = ; i <= n; i++) fa[i] = -;
que[] = , head = tail = , fa[] = , depth[] = ;
while(head <= tail)
{
int u = que[head++];
for(int tab = first[u], v; tab; tab = next[tab])
if(fa[v = to[tab]] == -)
{
fa[v] = u, favalue[v] = value[tab], depth[v] = depth[u] + ;
que[++tail] = v;
}
}
} inline int GetMax(int u, int v)
{
int ret = , level = M;
while(depth[u] != depth[v])
{
if(depth[u] < depth[v]) swap(u, v);
while(level && ( << level) > depth[u] - depth[v]) level--;
ret = max(ret, maxcnt[u][level]);
u = up[u][level];
}
level = M;
while(level && u != v)
{
while(level && ( << level) > depth[u]) level--;
while(level && up[u][level] == up[v][level]) level--;
ret = max(ret, maxcnt[u][level]);
ret = max(ret, maxcnt[v][level]);
u = up[u][level], v = up[v][level];
}
while(u != v)
{
ret = max(ret, favalue[u]);
ret = max(ret, favalue[v]);
u = fa[u], v = fa[v];
}
return ret;
} inline bool CompareByIndex(const EdgeType &a, const EdgeType &b)
{
return a.index < b.index;
} inline void Solve()
{
sort(edge + , edge + + m);
for(int i = ; i <= n; i++) fa[i] = i;
for(int i = ; i <= m; i++)
{
int u = Find(edge[i].u), v = Find(edge[i].v);
if(u != v)
{
Insert(edge[i].u, edge[i].v, edge[i].value);
Insert(edge[i].v, edge[i].u, edge[i].value);
ans += edge[i].value;
fa[u] = v;
}
} Bfs(); for(int i = ; i < M; i++)
{
if(( << i) > n) break;
for(int j = ; j <= n; j++)
if(i == )
{
up[j][i] = fa[j];
maxcnt[j][i] = favalue[j];
}
else
{
up[j][i] = up[up[j][i - ]][i - ];
maxcnt[j][i] = max(maxcnt[j][i - ], maxcnt[up[j][i - ]][i - ]);
}
} for(int i = ; i <= m; i++)
{
int u = edge[i].u, v = edge[i].v;
int ret = GetMax(u, v);
edge[i].ans = ans - ret + edge[i].value;
} sort(edge + , edge + + m, CompareByIndex);
for(int i = ; i <= m; i++) printf("%I64d\n", edge[i].ans);
} int main()
{
freopen("a.in", "r", stdin);
Input();
Solve();
return ;
}

CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge的更多相关文章

  1. CF Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树变种

    题目链接:http://codeforces.com/problemset/problem/609/E 大致就是有一棵树,对于每一条边,询问包含这条边,最小的一个生成树的权值. 做法就是先求一次最小生 ...

  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 ...

  3. 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 ...

  4. 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 ...

  5. 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 ...

  6. Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)

    题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...

  7. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

  8. codeforces 609E 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 ...

  9. Codeforces Edu3 E. Minimum spanning tree for each edge

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

随机推荐

  1. shell之数值运算

    Shell中声明变量默认是字符串, 要参与数值运算,可使用下面方式,简单,表示以数值方式.

  2. java 资源监控

    http://blog.csdn.net/huangzhaoyang2009/article/details/11860757 http://blog.csdn.net/cuker919/articl ...

  3. Oracle读写分离架构

    读写分离是架构分布式系统的一个重要思想.不少系统整体处理能力并不能同业务的增长保持同步,因此势必会带来瓶颈,单纯的升级硬件并不能一劳永逸.针对业务类型特点,需要从架构模式上进行一系列的调整,比如业务模 ...

  4. Android之WebView学习

    WebView常用方法 WebSettings 在使用WebView前我们都要进行相关的配置,常见的操作如下: WebSettings settings = mWebView.getSettings( ...

  5. ZOJ 2136 Longest Ordered Subsequence

    #include<time.h> #include <cstdio> #include <iostream> #include<algorithm> # ...

  6. 数据结构和算法 c#– 1.单项链表

    1.顺序存储结构 Array 1.引用类型(托管堆) 2.初始化时会设置默认值   2.链式存储结构 2.1.单向链表 2.2.循环链表 2.3.双向链表

  7. 在帝都的Android面试感想

    #第一次面试赤子城Android开发实习生 关于面试的表现和感想 1.没有准备充分就去面试(这是大忌,也就直接决定了结果) 我去面试Android,但是却不知道很多关于Android的基础知识,就是明 ...

  8. (转)ORA-12519: TNS:no appropriate service handler found 的问题处理。

    很多时候出现:ORA-12519: TNS:no appropriate service handler found 都是由于当前的连接数已经超出他能够处理的最大值了. 处理方法如下:摘自网上. se ...

  9. Java并发编程实现概览

    并发概览 >>同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通 ...

  10. 【转载】 Python 调整屏幕分辨率

    转载来自: http://www.cnblogs.com/fatterbetter/p/4115423.html 需要用windows的api,ChangeDisplaySettings 实现代码如下 ...