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. 词频统计_输入到文件_update

    /* 输入文件见337.in.txt 输出文件见338.out.txt */ #include <iostream> #include <cctype> #include &l ...

  2. Pyqt QSystemTrayIcon 实现托盘效果

    pyqt的托盘效果很好实现,在Pyqt的demo中有个例子 路径:PyQt4\examples\desktop\systray.py 今天我就仿这个Tray效果做效果 一. 创建UI trayicon ...

  3. Mongo DB Study: first face with mongo DB

    Mongo DB Study: first face with mongo DB 1.  study methods: 1.  Translate: I am the mongo DB organiz ...

  4. 【131031】html:hidden的使用

    一般来说,我们在使用Struts时,如果要在JSP隐式的传值给Action有两种情况: 1.要传的值是FromBean中的一个字段,你说的情况应该就是这种情况,例如需要在Edit页面中保存theID, ...

  5. PHP导出Excel一个方法轻松搞定

    /** * 导出数据为excel表格 *@param $data 一个二维数组,结构如同从数据库查出来的数组 *@param $title excel的第一行标题,一个数组,如果为空则没有标题 *@p ...

  6. 利用Roslyn构建一个简单的C#交互脚本引擎

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 微软的下一代编译器技术Roslyn是一个里程碑的技术,可以给.NET平台带来无限想象空间.比 ...

  7. 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2

    SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统    IA-SmartHome团队    2012.12     l  基于无线的智能家居解决方案,节省施工成本: l  基于能 ...

  8. memset中的sizeof

    记录memset中的sizeof的用法, unsigned char *buff = (unsigned char*) malloc(128 * sizeof(char)); //错误的:memset ...

  9. 在Salesforce中进行Report和Dashboard的配置

    用Report和Dashboard去图形化比较不同Object的信息是一个十分普遍的需求,当然我们可以完全用Visual Page和Classes去自定义对应的Report和Dashboard的功能. ...

  10. linux下SVN忽略文件/文件夹的方法

    linux下SVN忽略文件/文件夹的方法 假设想忽略文件temp 1. cd到temp所在的目录下: 2. svn propedit svn:ignore . 注意:请别漏掉最后的点(.表示当前目录) ...