E. Minimum spanning tree for each edge
 

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.

Examples
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

题意:

  给你n个点,m条边的带权无向图

  问你分别包含第i条边的 MST 权值 是多少

题解:

  先求一遍MST,这样知道了 总权值, 和某些 构成 MST 的 边

  假设 第 i 条边 在 当前求的 MST 的 边中

    那么 答案就是 这个 weight吧

  假如 第 i 条边 不在 当前 求的 MST 中,那么我们就加入在这个 MST的图中,会发现 无论 如何都构成 环

  那么 答案 就是 ,在这个环上 删除一条 除了加入的边 的权 值 最大的 那一条边

  问题就变成了 去MST 中 任意两点 的 边权 最大值

  这个问题的解法有很多

    我写的是LCA ,复杂度是logn * m

    还可以 直接 暴力 一点的写法

#include<bits/stdc++.h>
using namespace std; #pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 2e5+, M = 5e5+, inf = 2e9, mod = 1e9+; int fa[N],pa[N][],mx[N][],deep[N],vis[N],n,m;
LL weight;
LL ans[N];
vector<pii> G[N];
struct edge{
int u,v,w,id;
bool operator < (const edge &b) const {
return w<b.w;
}
}e[M];
int finds(int x) {return x == fa[x] ? x:fa[x]=finds(fa[x]);} void dfs(int u,int f,int c) {
pa[u][]=f, mx[u][]=c;
for(int i = ; i < G[u].size(); ++i) {
int to = G[u][i].first;
if(to == f) continue;
deep[to] = deep[u] + ;
dfs(to,u,G[u][i].second);
}
}
void solve() {
for(int i = ; i <= n; ++i) fa[i] = i;
sort(e+,e+m+);
for(int i = ; i <= m; ++i) {
int fx = finds(e[i].u);
int fy = finds(e[i].v);
if(fx == fy) continue;
G[e[i].u].push_back(MP(e[i].v,e[i].w));
G[e[i].v].push_back(MP(e[i].u,e[i].w));
fa[fx] = fy;
vis[i] = ;
weight += e[i].w;
}
dfs(,-,-);
for(int k = ; k < ; ++k) {
for(int i = ; i <= n; ++i) {
if(pa[i][k-] == -)
pa[i][k] = -, mx[i][k] = -;
else
pa[i][k] = pa[pa[i][k-]][k-],
mx[i][k] = max(mx[i][k-],mx[pa[i][k-]][k-]);
}
}
}
int Lca(int u,int v) {
if(deep[u] > deep[v]) swap(u,v);
int ret = ;
for(int k = ; k < ; ++k)
if((deep[v] - deep[u])>>k & )
ret = max(ret, mx[v][k]), v = pa[v][k];
if(u == v) return ret;
for(int k = ; k >= ; --k)
if(pa[u][k] != pa[v][k]) {
ret = max(ret, mx[u][k]), u = pa[u][k];
ret = max(ret, mx[v][k]), v = pa[v][k];
}
return max(ret, max(ret, max(mx[u][],mx[v][])));
}
int main() {
scanf("%d%d",&n,&m);
for(int i = ; i <= m; ++i) {
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
e[i].id = i;
}
solve();
for(int i = ; i <= m; ++i) {
if(vis[i]) ans[e[i].id] = weight;
else {
ans[e[i].id] = weight - Lca(e[i].u,e[i].v) + e[i].w;
}
}
for(int i = ; i <= m; ++i) printf("%I64d\n",ans[i]);
}

好暴力的写法 %

#include<bits/stdc++.h>
using namespace std; #define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==?a:gcd(b,a%b); } const int MAXN=;
const int MAXM=;
typedef struct E { int a,b,c,idx; } E;
bool operator<(const E &p,const E &q) { return p.c<q.c; } int n,m;
E e[MAXM]; int par[MAXN],sz[MAXN],val[MAXN]; ll ret;
int extra[MAXM];
int process(int a,int b,int c) {
int mx=;
while((par[a]!=a||par[b]!=b)&&a!=b) { if(par[b]==b||par[a]!=a&&sz[a]<=sz[b]) mx=max(mx,val[a]),a=par[a]; else mx=max(mx,val[b]),b=par[b]; }
if(a==b) return c-mx;
if(sz[a]<sz[b]) swap(a,b);
sz[a]+=sz[b]; par[b]=a; val[b]=c; ret+=c;
return ;
} void run() {
scanf("%d%d",&n,&m);
REP(i,m) scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].c),--e[i].a,--e[i].b,e[i].idx=i;
sort(e,e+m); ret=; REP(i,n) par[i]=i,sz[i]=;
REP(i,m) extra[e[i].idx]=process(e[i].a,e[i].b,e[i].c);
REP(i,m) printf("%I64d\n",ret+extra[i]);
} int main() {
run();
return ;
}

Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST的更多相关文章

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

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

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

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

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

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

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

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

  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. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

随机推荐

  1. PDF.js

    http://www.linuxidc.com/Linux/2015-06/118728.htm http://blog.csdn.net/xiangcns/article/details/42089 ...

  2. 解析sql语句中left_join、inner_join中的on与where的区别

    以下是对在sql语句中left_join.inner_join中的on与where的区别进行了详细的分析介绍,需要的朋友可以参考下 table a(id, type):id     type ---- ...

  3. Divide and conquer:Subset(POJ 3977)

    子序列 题目大意:给定一串数字序列,要你从中挑一定个数的数字使这些数字和绝对值最小,求出最小组合数 题目的数字最多35个,一看就是要数字枚举了,但是如果直接枚举,复杂度就是O(2^35)了,显然行不通 ...

  4. ios 中直接修改frame里边某个属性的简便方法

    参考:http://www.cnblogs.com/wengzilin/p/4359865.html 在iOS中view的frame属性使用地太频繁了,尤其是调UI的时候.我们知道,正常情况下我们无法 ...

  5. $(inherited) "$(SRCROOT) 修改.a文件的路径 --Library Search Paths

    $(inherited) "$(SRCROOT)/.a文件所在的文件名" //如果有多个.a文件格式就像这样 $(inherited) "$(SRCROOT)/xxxx& ...

  6. Cannot change version of project facet Dynamic Web Module to 3.0

    背景描述: 最近在开发项目时,老是报错说:Project is not Dynamic Web Module 3.0.右击项目选择属性进行修改时出现以下错误: 这让我很是恼火,后来终于找到了万能的解决 ...

  7. tableView滚到最后一行

    dispatch_async(dispatch_get_main_queue(), ^{ [_tableview scrollToRowAtIndexPath:[NSIndexPath indexPa ...

  8. Codeforces Round #344 (Div. 2)(按位或运算)

    Blake is a CEO of a large company called "Blake Technologies". He loves his company very m ...

  9. PHP超全局变量

    PHP提供了九种超全局变量(数组) 1 $_GET //地址栏上获得的值 2 $_POST //POST表单发送的数据 3 $_REQUEST //GET和POST的内容全都有 4 $_SERVER ...

  10. mysql的存储过程

    mysql5中开始引入存储过程,存储过程是一组为了完成特定功能的sql语句集,经编译后存储在数据库中. 存储过程的特点(优点): 1:减小网络通信量.调用一个行数不多的存储过程与直接高用SQL语名的网 ...