题目链接: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. MinGW GCC下sleep()函数问题

    在MinGW GCC下编译带sleep()函数的测试程序,不管是包含了unistd.h头文件,还是stdio.h.stdlib.h头文件,就是找不到该函数的定义!在linux下,sleep()函数的头 ...

  2. tornado中使用torndb,连接数过高的问题

    问题背景 最近新的产品开发中,使用了到了Tornado和mysql数据库.但在基本框架完成之后,我在开发时候发现了一个很奇怪的现象,我在测试时,发现数据库返回不了结果,于是我在mysql中输入show ...

  3. 函数buf_page_init

    /********************************************************************//** Inits a page to the buffer ...

  4. SQL查看数据库所用用户表数量和使用的空间

    SQL Server数据库管理员通常硬盘空间奋斗,不断努力清理“表”,撰写许多查询,发现该表使用的硬盘空间. 本文介绍了如何查询系统表的空间使用情况,帮助数据库管理员识别正在使用最多的空间,以便存档旧 ...

  5. CodeForces Round #280 (Div.2)

    A. Vanya and Cubes 题意: 给你n个小方块,现在要搭一个金字塔,金字塔的第i层需要 个小方块,问这n个方块最多搭几层金字塔. 分析: 根据求和公式,有,按照规律直接加就行,直到超过n ...

  6. 完全二叉树的高度为什么是对lgN向下取整

    完全二叉树的高度为什么是对lgN向下取整呢? 说明一下这里的高度:只有根节点的树高度是0. 设一棵完全二叉树节点个数为N,高度为h.所以总节点个数N满足以下不等式: 1 + 21 + 22 +……+ ...

  7. Oracle中HWM与数据库性能的探讨

    Oracle中HWM与数据库性能的探讨 一.什么是高水位 HWM(high water mark),高水标记,这个概念在segment的存储内容中是比较重要的.简单来说,HWM就是一个segment中 ...

  8. 一天一个Java基础——序列化

    1.概念 Java的“对象序列化”能将一个实现了Serializable接口的对象转换成一组byte,这样日后要用这个对象的时候,能把这些byte数据恢复出来,并据此重新构建那个对象. 对象序列化能实 ...

  9. Solr部署如何启动

    我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 1.准 ...

  10. RegExp类型和text()方法

    ECMAScript通过RegExp类型来支持正则表达式 RegExp 实例方法:text() 它接受一个字符串参数,在模式与该参数匹配的情况下返回true,否则返回false,通常用在if语句中 / ...