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

大致就是有一棵树,对于每一条边,询问包含这条边,最小的一个生成树的权值。

做法就是先求一次最小生成树,标记最小生成树上的边,对于这些边,直接就是原始最小生成树。否则必然可以在去掉u到v路径上最长边,再加上边u->v,这一定是包含此边最小的生成树。

查询最长边,可以用树链剖分,也可以树上倍增。

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#include <cassert> using namespace std; const int N=2e5+;
const int INF=0x3f3f3f3f;
struct Node {
int u,v,w;
int id;
bool operator < (const Node &o) const {
return w<o.w;
}
}node[N];
struct Edge{
int to,next,w;
}edge[N<<];
int idx,head[N];
void addedge(int u,int v,int w){
++idx;
edge[idx].to=v;
edge[idx].next=head[u];
edge[idx].w=w;
head[u]=idx;
}
int dep[N];
int par[N][];
int dis[N][];
void dfs(int u,int f,int d){
dep[u]=d;
for (int k=head[u];k;k=edge[k].next){
int v=edge[k].to;
if (v==f) continue;
par[v][]=u;
dis[v][]=edge[k].w;
dfs(v,u,d+);
}
}
int kthA(int u,int k) {
for (int i=;i>=;i--) {
if (k>=(<<i)) {
k-=(<<i);
u=par[u][i];
}
}
return u;
}
int kthD(int u,int k) {
int ret=;
for (int i=;i>=;i--) {
if (k>=(<<i)) {
k-=(<<i);
ret=max(ret,dis[u][i]);
u=par[u][i];
}
}
return ret;
}
void calc(int n) {
for (int i=;i<=;i++) {
int k=<<(i-);
for (int j=;j<=n;j++) {
par[j][i]=par[par[j][i-]][i-];
dis[j][i]=max(dis[j][i-],dis[par[j][i-]][i-]);
}
}
}
int get(int u,int v){
if(dep[u]<dep[v])swap(u,v);
int ret=kthD(u,dep[u]-dep[v]);
u=kthA(u,dep[u]-dep[v]);
if(u==v)return ret;
for(int i=;i>=;i--){
if(par[u][i]==par[v][i])continue;
ret=max(ret,dis[u][i]);
ret=max(ret,dis[v][i]);
u=par[u][i];
v=par[v][i];
}
ret=max(ret,dis[u][]);
ret=max(ret,dis[v][]);
return ret;
}
int fa[N];
int find(int x) {
if (fa[x]==x)
return x;
return fa[x]=find(fa[x]);
}
bool mark[N];
long long ret[N];
int main () {
ios_base::sync_with_stdio(false);
int n,m;
while (cin>>n>>m) {
for (int i=;i<=m;i++) {
cin>>node[i].u>>node[i].v>>node[i].w;
node[i].id=i;
mark[i]=false;
}
sort(node+,node++m);
long long sum=;
for (int i=;i<=n;i++)
fa[i]=i;
idx=;memset(head,,sizeof head);
for (int i=;i<=m;i++) {
int u=node[i].u;
int v=node[i].v;
int w=node[i].w;
int id=node[i].id;
int fu=find(u);
int fv=find(v);
if (fu==fv) continue;
fa[fu]=fv;
sum+=w;
mark[id]=true;
addedge(u,v,w);
addedge(v,u,w);
}
dfs(,-,);
calc(n);
for (int i=;i<=m;i++) {
int id=node[i].id;
int u=node[i].u;
int v=node[i].v;
int w=node[i].w;
if (mark[id]) ret[id]=sum;
else {
int mx=get(u,v);
ret[id]=sum+w-mx;
}
}
for (int i=;i<=m;i++)
cout<<ret[i]<<endl;
}
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

    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 最小生成树+树链剖分+线段树

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

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

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

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

  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. 从depth buffer中构建view-space position

    观察透视投影矩阵: 对于x和y,矩阵变换只是一个缩放系数,那么逆变换就是缩放系数的倒数,所以 设Xndc Yndc为NDC空间中的XY坐标,Xview Yview Zview为view space中的 ...

  2. 3997: [TJOI2015]组合数学

    3997: [TJOI2015]组合数学 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 247  Solved: 174[Submit][Status ...

  3. .Net程序员学用Oracle系列(21):分组查询(GROUP BY)

    1.GROUP BY 标准分组 1.1.GROUP BY 概述 1.2.WHERE 和 HAVING 的区别? 2.GROUP BY 扩展分组 2.1.ROLLUP 分组 2.2.CUBE 分组 2. ...

  4. iOS PureLayout使用

    PureLayout是iOS Auto Layout的终端API,强大而简单.由UIView.NSArray和NSLayoutConstraint类别组成.PureLayout为大多数Auto Lay ...

  5. C# 使用 USB转串 接收数据 问题

    C# 使用 USB转串 接收数据的 问题 硬件设备是MicroUSB接口,通过USB转串驱动接入PC机.自己用winForm写了一个读取串口数据的小程序,总是接收不到数据. 用传sscom32串口工具 ...

  6. ASP.NET Core MVC 源码学习:Routing 路由

    前言 最近打算抽时间看一下 ASP.NET Core MVC 的源码,特此把自己学习到的内容记录下来,也算是做个笔记吧. 路由作为 MVC 的基本部分,所以在学习 MVC 的其他源码之前还是先学习一下 ...

  7. (9)集合之Set,HashSet,TreeSet

    TreeSet子类 注意事项: 1.向TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储 2.往TreeSet添加元素的时候,如果元素本身不具备自 ...

  8. SLF4J 的几种实际应用模式--之三:JCL-Over-SLF4J+SLF4J

    我们前面已经讲过了 SLF4J 的两种用法:SLF4J+Log4J  和 SLF4J+Logback,那是在比较理想的情况下,所用组件只使用了 SLF4J 这一种统一日志框架的时候.可是 JCL 一直 ...

  9. SharePoint 切换用户的小技巧

    前言 从SharePoint 2013开始,SharePoint就已经去掉了”Sign in as Different User”这个功能,也就是无法切换用户登录.当然,后来我们通过修改CONTROL ...

  10. Ef+T4模板实现代码快速生成器

    转载请注明地址:http://www.cnblogs.com/cainiaodage/p/4953601.html 效果如图,demo(点击demo可下载案例) 项目结构如图 T4BLL添加BLL.t ...