CF Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树变种
题目链接: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 最小生成树变种的更多相关文章
- 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 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 (最小生成树+树链剖分)
题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...
- 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 ...
- 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 ...
- [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 ...
- 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 ...
随机推荐
- SVNManager配置
1.svn与apache的安装 yum install -y subversion httpd httpd.conf添加如下内容: LoadModule dav_svn_module module ...
- 3DES 加密 解密
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #c91b13 } p.p2 { margin: 0.0px 0. ...
- Effective Modern C++ Item 27:重载universal references
假设有一个接收universal references的模板函数foo,定义如下: template<typename T> void foo(T&& t) { cout ...
- Broken pipe错误终极解释
叙述 想必或多或少在Java的服务器都会遇到过这种异常,如下图 由于Java偏上层,日常开发接触系统底层的机会偏少,要搞清楚什么原因导致的这种异常,肯定是先要百度google一番. 网络 ...
- linux 根分区扩展
linux根分区扩容 今天网站上传图片出问题了,一开始还以为是程序问题,后来发现原来是服务器存储空间不够,明明有200G的磁盘空间,没理由这么快就用完,查了一下分区情况,原来有两块磁盘,根分区只挂载在 ...
- Android设计模式之代理模式
代理模式: 为其他对象提供一种代理以控制对这个对象的访问 Subject类定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy inte ...
- JS Math.round()方法原理
请先测试代码: <!doctype html> <html lang="en"> <head> <meta charset="U ...
- C#实现不影响当前线程情况下间隔一定的时间执行一段代码
大家知道C#间隔一定时间去执行一段代码,常用的有 1. Thread.Sleep(多少毫秒); 2. 使用Timer控件间隔一定的时间,设置执行一次 以上两种方法,实现起来不难,弊端在于会阻塞当前线程 ...
- 20155323 2016-2017-2 《Java程序设计》第5周学习总结
20155323 2016-2017-2 <Java程序设计>第5周学习总结 教材学习内容总结 异常处理 提供两种异常处理机制:捕获异常和声明抛弃异常. 捕获异常:在Java程序运行过程中 ...
- 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件
老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...