题目链接:http://codeforces.com/contest/609/problem/E

给你n个点,m条边。

问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少。

先求出最小生成树,树链剖分一下最小生成树。然后枚举m条边中的每条边,要是这条边是最小生成树的其中一边,则直接输出最小生成树的答案;否则就用树剖求u到v之间的最大边,然后最小生成树权值减去求出的最大边然后加上枚举的这条边就是答案。

 #include <bits/stdc++.h>
using namespace std;
typedef __int64 LL;
const int MAXN = 2e5 + ;
struct data {
int from , to , index;
bool flag;
LL cost;
bool operator <(const data& cmp) const {
return cost < cmp.cost;
}
}a[MAXN] , b[MAXN];
struct EDGE {
int next , to;
LL cost;
}edge[MAXN << ];
int head[MAXN] , tot;
int par[MAXN] , dep[MAXN] , son[MAXN] , size[MAXN];
int top[MAXN] , id[MAXN] , cnt; bool cmp(const data& a , const data &b) {
return a.index < b.index;
} void init(int n) {
memset(head , - , sizeof(head));
for(int i = ; i <= n ; ++i)
par[i] = i;
} int Find(int u) {
if(par[u] == u)
return u;
return par[u] = Find(par[u]);
} inline void add(int u , int v , LL cost) {
edge[tot].to = v;
edge[tot].next = head[u];
edge[tot].cost = cost;
head[u] = tot++;
} LL mst(int m) {
LL sum = ;
int f = ;
for(int i = ; i <= m ; ++i) {
int u = Find(a[i].from) , v = Find(a[i].to);
if(u != v) {
par[u] = v;
sum += a[i].cost;
a[i].flag = true;
add(a[i].from , a[i].to , a[i].cost);
add(a[i].to , a[i].from , a[i].cost);
++f;
b[f].from = a[i].from , b[f].to = a[i].to , b[f].cost = a[i].cost;
}
else {
a[i].flag = false;
}
}
return sum;
} void dfs1(int u , int p , int d) {
dep[u] = d , par[u] = p , son[u] = u , size[u] = ;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dfs1(v , u , d + );
if(size[v] >= size[son[u]])
son[u] = v;
size[u] += size[v];
}
} void dfs2(int u , int p , int t) {
top[u] = t , id[u] = ++cnt;
if(son[u] != u)
dfs2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == son[u] || v == p)
continue;
dfs2(v , u , v);
}
} struct SegTree {
int l , r;
LL Max;
}T[MAXN << ]; void build(int p , int l , int r) {
int mid = (l + r) >> ;
T[p].l = l , T[p].r = r;
if(l == r) {
return ;
}
build(p << , l , mid);
build((p << )| , mid + , r);
} void updata(int p , int pos , LL num) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == T[p].r && T[p].l == pos) {
T[p].Max = num;
return ;
}
if(pos <= mid) {
updata(p << , pos , num);
}
else {
updata((p << )| , pos , num);
}
T[p].Max = max(T[p << ].Max , T[(p << )|].Max);
} LL query(int p , int l , int r) {
int mid = (T[p].l + T[p].r) >> ;
if(T[p].l == l && T[p].r == r) {
return T[p].Max;
}
if(r <= mid) {
return query(p << , l , r);
}
else if(l > mid) {
return query((p << )| , l , r);
}
else {
return max(query(p << , l , mid) , query((p << )| , mid + , r));
}
} LL find_max(int u , int v) {
int fu = top[u] , fv = top[v];
LL Max = ;
while(fv != fu) {
if(dep[fu] >= dep[fv]) {
Max = max(Max , query( , id[fu] , id[u]));
u = par[fu];
fu = top[u];
}
else {
Max = max(Max , query( , id[fv] , id[v]));
v = par[fv];
fv = top[v];
}
}
if(u == v)
return Max;
else if(dep[u] > dep[v])
return max(Max , query( , id[son[v]] , id[u]));
else
return max(Max , query( , id[son[u]] , id[v]));
} int main()
{
int n , m;
scanf("%d %d" , &n , &m);
if(m == ) {
printf("");
return ;
}
init(n);
for(int i = ; i <= m ; ++i) {
scanf("%d %d %lld" , &a[i].from , &a[i].to , &a[i].cost);
a[i].index = i;
}
sort(a + , a + m + );
LL mst_len = mst(m);
dfs1( , , );
dfs2( , , );
build( , , cnt);
for(int i = ; i <= n - ; ++i) {
if(dep[b[i].from] < dep[b[i].to])
swap(b[i].from , b[i].to);
updata( , id[b[i].from] , b[i].cost);
}
sort(a + , a + m + , cmp);
for(int i = ; i <= m ; ++i) {
if(a[i].flag)
printf("%lld\n" , mst_len);
else {
LL temp = find_max(a[i].from , a[i].to);
printf("%lld\n" , mst_len - temp + a[i].cost);
}
}
return ;
}

Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)的更多相关文章

  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 LCA/(树链剖分+数据结构) + MST

    E. Minimum spanning tree for each edge   Connected undirected weighted graph without self-loops and ...

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

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

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

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

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

  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. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

随机推荐

  1. 双方都在线,qq总是离线发文件

    这是qq支持多地登录后出现的问题. 原因:1.当您传文件给对方,对方是多终端登录(或者开通移动在线功能)的情况下,为了保证对方一定能收到该文件,我们会智能的为用户切换到离线文件,对方会相应在所在的终端 ...

  2. 1218. Episode N-th: The Jedi Tournament(bfs)

    1218 简答题 对于当前点 判断每个点是否可达 #include <iostream> #include<cstdio> #include<cstring> #i ...

  3. bzoj2251

    以前看到这道题想到的是SA,做起来不是很美观 学了SAM之后,这题简直是随便搞 ..,'] of longint; s,sa,mx,w,fa:..] of longint; i,n,last,t:lo ...

  4. UVa 11489 (博弈) Integer Game

    一个数字能被3整除就等价于这个数的各个数字之和被3整除. 所以一开始的时候先要拿一个能使剩下的数字是3的倍数的数. 然后就一直拿0.3.6.9直到某人不能再拿为止. #include <cstd ...

  5. [HUD 1195] Open the Lock

    Open the Lock Problem Description Now an emergent task for you is to open a password lock. The passw ...

  6. android通过httpClient请求获取JSON数据并且解析

    使用.net创建一个ashx文件,并response.write  json格式 public void ProcessRequest(HttpContext context) { context.R ...

  7. codevs 3732 解方程

    神题不可言会. f(x+p)=f(x)(mod p) #include<iostream> #include<cstdio> #include<cstring> # ...

  8. noip2008提高组题解

    第一题:笨小猴 模拟   第二题:火柴棒等式 搜索 深搜不用说,确定出两个加数然后判断能否拼出等式. 枚举确实不太好搞,因为枚举范围不确定,太大了容易超时,太小了容易漏解.不过这题的数据貌似很温和,我 ...

  9. 《C++ Primer 4th》读书笔记 第9章-顺序容器

    原创文章,转载请注明出处:http://www.cnblogs.com/DayByDay/p/3936460.html

  10. Oracle 课程五之优化器和执行计划

    课程目标 完成本课程的学习后,您应该能够: •优化器的作用 •优化器的类型 •优化器的优化步骤 •扫描的基本类型 •表连接的执行计划 •其他运算方式的执行计划 •如何看执行计划顺序 •如何获取执行计划 ...