Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
2 seconds
256 megabytes
standard input
standard output
Connected undirected weighted graph without self-loops and multiple edges is given. Graph contains n vertices and m edges.
For each edge (u, v) find the minimal possible weight of the spanning tree that contains the edge (u, v).
The weight of the spanning tree is the sum of weights of all edges included in spanning tree.
First line contains two integers n and m (1 ≤ n ≤ 2·105, n - 1 ≤ m ≤ 2·105) — the number of vertices and edges in graph.
Each of the next m lines contains three integers ui, vi, wi (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ wi ≤ 109) — the endpoints of the i-th edge and its weight.
Print m lines. i-th line should contain the minimal possible weight of the spanning tree that contains i-th edge.
The edges are numbered from 1 to m in order of their appearing in input.
5 7
1 2 3
1 3 1
1 4 5
2 3 2
2 5 3
3 4 2
4 5 4
9
8
11
8
8
8
9
题意:给你n个点,m条边;
第i条为必选边,求最小的生成树;
思路:先建好一颗最小生成树,如果边在生成树上,输出最小的即可;
对于不在树上的如何求解:
原来建好的一棵树,再加入一条边,会使得形成一个环,去查找原来最小生成树中u到v最大的边权,最小生成树的权值减去最大的边权+当前的边权即使答案;
无更新的区间最大值,可以用倍增的写法;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define pi (4*atan(1.0))
#define eps 1e-4
#define bug(x) cout<<"bug"<<x<<endl;
const int N=2e5+,M=1e6+,inf=;
const ll INF=1e18+,mod=; ///数组大小
struct edge
{
int v,next;
} edge[N<<];
int head[N<<],edg,id,n;
/// 树链剖分 int fa[N],dep[N],son[N],siz[N]; // fa父亲,dep深度,son重儿子,siz以该点为子树的节点个数
int ran[N],top[N],tid[N],num[N]; // tid表示边的标号,top通过重边可以到达最上面的点,ran表示标记tid
void init()
{
memset(son,-,sizeof(son));
memset(head,-,sizeof(head));
edg=;
id=;
} void add(int u,int v)
{
edg++;
edge[edg].v=v;
edge[edg].next=head[u];
head[u]=edg;
} void dfs1(int u,int fath,int deep)
{
fa[u]=fath;
siz[u]=;
dep[u]=deep;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==fath)continue;
dfs1(v,u,deep+);
siz[u]+=siz[v];
if(son[u]==-||siz[v]>siz[son[u]])
son[u]=v;
}
} void dfs2(int u,int tp)
{
tid[u]=++id;
top[u]=tp;
ran[tid[u]]=u;
if(son[u]==-)return;
dfs2(son[u],tp);
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].v;
if(v==fa[u])continue;
if(v!=son[u])
dfs2(v,v);
}
} struct SGT
{
int maxx[N<<];
void pushup(int pos)
{
maxx[pos]=max(maxx[pos<<],maxx[pos<<|]);
}
void build(int l,int r,int pos)
{
if(l==r)
{
maxx[pos]=num[ran[l]];
return;
}
int mid=(l+r)>>;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
pushup(pos);
}
int query(int L,int R,int l,int r,int pos)
{
//cout<<L<<" "<<R<<" "<<l<<" "<<r<<endl;
if(L<=l&&r<=R)return maxx[pos];
int mid=(l+r)>>;
int ans=;
if(L<=mid)ans=max(ans,query(L,R,l,mid,pos<<));
if(R>mid) ans=max(ans,query(L,R,mid+,r,pos<<|));
return ans;
}
}tree; int up(int l,int r)
{
int ans=;
while(top[l]!=top[r])
{
if(dep[top[l]]<dep[top[r]])swap(l,r); ans=max(ans,tree.query(tid[top[l]],tid[l],,n,));
l=fa[top[l]];
} if(dep[l]<dep[r])swap(l,r);
if(l==r)return ans;
ans=max(ans,tree.query(tid[son[r]],tid[l],,n,));
return ans;
}
/// 克鲁斯卡尔
struct is
{
int u,v,w,pos;
operator <(const is &x)const
{
return w<x.w;
}
}a[N];
int fafa[N],ans[N];
int Find(int x)
{
return x==fafa[x]?x:fafa[x]=Find(fafa[x]);
}
ll out[N];
int main()
{
init();
int m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w),a[i].pos=i;
sort(a+,a++m);
ll minn=;
for(int i=;i<=n;i++)
fafa[i]=i;
for(int i=;i<=m;i++)
{
int x=Find(a[i].u);
int y=Find(a[i].v);
if(x!=y)
{
add(a[i].u,a[i].v);
add(a[i].v,a[i].u);
fafa[x]=y;
minn+=a[i].w;
ans[i]=;
}
}
dfs1(,-,);
dfs2(,);
for(int i=;i<=m;i++)
{
if(ans[i])
{
if(fa[a[i].u]==a[i].v)
num[a[i].u]=a[i].w;
else
num[a[i].v]=a[i].w;
}
}
tree.build(,n,);
for(int i=;i<=m;i++)
{
if(ans[i])out[a[i].pos]=minn;
else
{
int x=up(a[i].u,a[i].v);
out[a[i].pos]=minn-x+a[i].w;
}
}
for(int i=;i<=m;i++)
printf("%lld\n",out[i]);
return ;
}
Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树的更多相关文章
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge (最小生成树+树链剖分)
题目链接:http://codeforces.com/contest/609/problem/E 给你n个点,m条边. 问枚举每条边,问你加这条边的前提下组成生成树的权值最小的树的权值和是多少. 先求 ...
- 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 ...
- 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
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- Aizu 2450 Do use segment tree 树链剖分+线段树
Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
随机推荐
- Requests+BeautifulSoup+正则表达式爬取猫眼电影Top100(名称,演员,评分,封面,上映时间,简介)
# encoding:utf-8 from requests.exceptions import RequestException import requests import re import j ...
- python PIL 图像处理操作
python PIL 图像处理 # 导入Image库 import Image # 读取图片 im = Image.open("1234.jpg") # 显示图片 im.show( ...
- 自学Java第四周的总结
在这一周里我主要把以前学的知识复习了一遍,加深了自己对那些知识点的熟悉程度.另外我还学习了有关于Java中的异常处理.继承.抽象类等相关知识.了解了其基本意义,即继承是java面向对象编程技术的一块基 ...
- vue 生命周期钩子的理解 watch computed
一 理解vue的生命周期,首先需要注意几个关键字 1. el :选择器 2. $el:对应选择器的template模板(html代码) 3. render:也是vue实例中的一项,其参数更接近vue ...
- ubuntu_virtualenv
sudo pip install virtualenv 1.安装virtualenv(需要先安装pip): $ [sudo] pip install virtualenv 2.创建虚拟环境: $ vi ...
- 使用URLConnection进行访问
package test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOExcepti ...
- 关于HashSet的equals和hashcode的重写
关于HashSet的equals和hashcode的重写:package Test; import java.util.HashSet; import java.util.Set; public cl ...
- Mysql 存储过程中使用多游标
Mysql 存储过程中使用多游标 drop procedure IF EXISTS test_proc_1; create procedure test_proc_1() begin ; ) ; ) ...
- shell脚本一键安装nginx
依赖包安装包放在一起, 直接执行这个脚本就行. #!/bin/bash #--------------------------------------------------------------- ...
- poj 2942 Knights of the Round Table - Tarjan
Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress ...