Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)
题目链接: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 (最小生成树+树链剖分)的更多相关文章
- 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 ...
- 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 ...
- CF Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树变种
题目链接:http://codeforces.com/problemset/problem/609/E 大致就是有一棵树,对于每一条边,询问包含这条边,最小的一个生成树的权值. 做法就是先求一次最小生 ...
- 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 ...
- 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 ...
- 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 ...
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- 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 ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
随机推荐
- HttpContext.Current.RewritePath方法重写URL
if (!IsPostBack) { //如果请求ID为空,则重写URL为:~/index.aspx?ID=shouji.115sou.com if (Request.QueryString[&quo ...
- POJ 2584 T-Shirt Gumbo (二分图多重最大匹配)
题意 现在要将5种型号的衣服分发给n个参赛者,然后给出每个参赛者所需要的衣服的尺码的大小范围,在该尺码范围内的衣服该选手可以接受,再给出这5种型号衣服各自的数量,问是否存在一种分配方案使得每个选手都能 ...
- I.MX6 git patch
/********************************************************************** * I.MX6 git patch * 说明: * 之前 ...
- datatables 服务器返回数据后的处理-表格数据属性的操作方法(ajax.dataSrc)
http://dt.thxopen.com/reference/option/ajax.dataSrc.html http://datatables.net/reference/option/ajax ...
- oracle中怎么查看存储过程的源码
今天想找几天前写的存储过程的源码看看,发现自己熟悉的命令怎么都不好使,要不提示标示符错误要不就是提示未选定行,通过baidu得知type跟name变量要弄成大写的.. select text from ...
- z-index的妙用
总是在纠结一个问题,当然我是前端初学者.这个问题就是,一个元素放在另一个元素里面,总希望它显示时,但是别撑开元素.这个时候一定要想到z-index. 例如今天写的一个浮动在导航栏下面的一个图片,我用的 ...
- android adt与android sdk有什么关系,他们在开发中各起到什么作用
ADT(Android Development Tools):目前Android开发所用的开发工具是Eclipse,在Eclipse编译IDE环境中,安装ADT,为Android开发提供开发工具的升级 ...
- Domain Name System (DNS)
1.DNS和WINS的作用 DNS:(Domain Name Server,域名服务)用于实现域名和IP地址的相互转换. WINS:(Windows Internet Name Service) 用来 ...
- iE6、7、8、9、10、11兼容的Cookie
<%@ Master Language="C#" Debug="true" AutoEventWireup="true" Inheri ...
- HDU 5278 PowMod 数论公式推导
题意:中文题自己看吧 分析:这题分两步 第一步:利用已知公式求出k: 第二步:求出k然后使用欧拉降幂公式即可,欧拉降幂公式不需要互质(第二步就是BZOJ3884原题了) 求k的话就需要构造了(引入官方 ...