Stree
题目
给出n个点,m条有权边,现对于每一条边,你需要回答出包含这条边的最小生成树的总边权值。
分析
首先我们可以构造一个对于这n个点,m条有权边的最小生成树,显然,这是一棵最小的生成树。
那么这棵生成树的边的答案就是这棵生成树的总边权。
然后,就要考虑这棵生成树的其他边了。
在这棵生成树上,如果我们给它加一条新的边,那么,一定会形成一个环。
所以,我们把这个环中最大的边(当然不是新加入的边啦)删掉,这棵新树的总边权就是答案。
怎样删掉这个环中最大的边呢?
发现,实际上就是删掉加入的新边的两个顶点在原树上的路径上最大的边,那么就可以打倍增lca找到最大的边。(想打树链剖分也可以,不拦你)
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=1000000007;
const long long N=200006;
using namespace std;
long long ans[N],way[N][3],n,m,fa[N],sum,bef[N],last[N*2],next[N*2],to[N*2],f[N][20],g[N][20],tot,v[N*2],deep[N];
void bj(long long x,long long y,long long z)
{
	next[++tot]=last[x];
	last[x]=tot;
	to[tot]=y;
	v[tot]=z;
}
void q(long long l,long long r)
{
	long long i=l,j=r,mid=way[(l+r)/2][0],e;
	while(i<j)
	{
		while(way[i][0]<mid) i++;
		while(way[j][0]>mid) j--;
		if(i<=j)
		{
			e=way[i][0];
			way[i][0]=way[j][0];
			way[j][0]=e;
			e=way[i][1];
			way[i][1]=way[j][1];
			way[j][1]=e;
			e=way[i][2];
			way[i][2]=way[j][2];
			way[j][2]=e;
			e=bef[j];
			bef[j]=bef[i];
			bef[i]=e;
			i++;
			j--;
		}
	}
	if(i<r) q(i,r);
	if(l<j) q(l,j);
}
long long get(long long x)
{
	if(fa[x]==x) return x;
	fa[x]=get(fa[x]);
	return fa[x];
}
void dg(long long x,long long y)
{
	for(long long i=last[x];i;i=next[i])
	{
		long long j=to[i];
		if(j!=y)
		{
			deep[j]=deep[x]+1;
			g[j][0]=x;
			f[j][0]=v[i];
			dg(j,x);
		}
	}
}
long long lca(long long x,long long y)
{
	long long l;
    if(deep[x]<=deep[y])
    {
        l=x;
        x=y;
        y=l;
    }
    long long p=0;
    for(long long i=log2(n);i>=0;i--)
    {
    	if(deep[g[x][i]]>=deep[y])
    	{
    		p=max(p,f[x][i]);
    		x=g[x][i];
		}
	}
    for(long long i=log2(n);i>=0;i--)
    {
    	if(g[x][i]!=g[y][i])
    	{
    		p=max(p,max(f[x][i],f[y][i]));
    		x=g[x][i];
    		y=g[y][i];
		}
	}
    if(x!=y) p=max(p,max(f[x][0],f[y][0]));
	return p;
}
int main()
{
	freopen("street.in","r",stdin);
	freopen("street.out","w",stdout);
	scanf("%lld%lld",&n,&m);
	for(long long i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&way[i][1],&way[i][2],&way[i][0]);
		fa[i]=i;
		bef[i]=i;
	}
	q(1,m);
	long long k=0;
	sum=0;
	for(long long i=1;i<=m,k<n-1;i++)
	{
		long long x=get(way[i][1]);
		long long y=get(way[i][2]);
		if(x==y) continue;
		k++;
		ans[bef[i]]=1;
		bj(way[i][1],way[i][2],way[i][0]);
		bj(way[i][2],way[i][1],way[i][0]);
		sum+=way[i][0];
		fa[x]=y;
	}
	deep[1]=1;
	dg(1,0);
	for(long long i=1;i<=log2(n);i++)
		for(long long j=1;j<=n;j++)
		{
			g[j][i]=g[g[j][i-1]][i-1];
			f[j][i]=max(f[j][i-1],f[g[j][i-1]][i-1]);
		}
	for(long long i=1;i<=m;i++)
	{
		if(!ans[bef[i]])
		{
			ans[bef[i]]=sum-lca(way[i][1],way[i][2])+way[i][0];
		}
		else
			ans[bef[i]]=sum;
	}
	for(long long i=1;i<=m;i++)
		printf("%lld\n",ans[i]);
}
Stree的更多相关文章
- jQuery可拖拽排序列表jquery-sortable-lists
		jquery-sortable-lists可以通过鼠标进行拖动排列树型菜单,可以定义某个列表元素是否拖动,拖动后回调,点击可以折叠树型结点,可以用来在后台模仿wordpress后台拖动菜单,实现多级菜 ... 
- HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)
		http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ... 
- UVa 712 S树
		https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ... 
- javascript 设计模式-----策略模式
		在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ... 
- ps, top, pstree
		ps 查看当前终端所启动的进程, 不加选项只查看当前终端的进程 PID TTY TIME CMD 2398 pts/1 00:00:00 bash 3625 pts/1 00:00:00 ps #PI ... 
- SQL复习
		1.select SELECT LastName,FirstName FROM Persons SELECT * FROM Persons 2.distinct SELECT DISTINCT Com ... 
- HYSBZ 1588 营业额统计
		题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588 题意:详见题面,中文 思路:平衡树的模板题. 可用Treap,Splay,Scape ... 
- FTP客户端上传下载Demo实现
		1.第一次感觉MS也有这么难用的MFC类: 2.CFtpFileFind类只能实例化一个,多个实例同时查找会出错(因此下载时不能递归),采用队列存储目录再依次下载: 3.本程序支持文件夹嵌套上传下载: ... 
- Criteria查询数据
		Criteria介绍: Criteria查询是Hibernate提供的一种查询方式,与HQL基于字符串的查询形式完全不同.Hibernate提供了org.hiberanee.Criteria 接口.o ... 
随机推荐
- diff()函数
			1 diff()是将原来的数据减去移动后的数据. 在numpy和pandas中都能调用. pandas的调用方法: import pandas as pd df = pd.DataFrame( {'a ... 
- gzip, deflate  delphi xe 2  解码 成功  哈哈
			2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 http://bbs.csdn.net/topics/190020986 ... 
- gitlab+jenkins 搭建
			继前一篇gitlab,这一篇介绍jenkins搭建并与gitlab进行集成---这里不是详细的步骤 环境系统:centos 7.3 jenkins版本:jenkins-2.176.1-1.1.noar ... 
- java调用com组件com4j
			com4j A Java library that allows Java applications to seemlessly interoperate with Microsoft Compone ... 
- lnmp一键安装包卸载mysql,重新安装报错mysql57-community-release conflicts with mysql-community-release-el6-5.noarch
			环境:CentOS Linux release 7.6.1810 lnmp1.5 独立下载mysql仓库 wget -i -c http://dev.mysql.com/get/mysql57-com ... 
- 【Qt开发】设置中心窗口 setCentralWidget
			http://blog.csdn.net/qter_wd007/article/details/7028920 Qt程序中的主窗口通常具有一个中心窗口部件.从理论上来讲,任何继承自QWidget的类的 ... 
- linux文件属性软链接
			linux里的软链接 相当于windows系统中的快捷方式 软链接总结: 1.删除源文件,软链接文件依然存在,但是无法访问指向源文件路径内容. 2.失效时候一般是白字红底闪烁显示. test -> ... 
- 红帽学习笔记[RHCSA] 第二课[文件、目录、相关命令]
			第二课 常用的目录结构与用途 / 根目录 /boot 存储的是系统起动时的信息和内核等 /dev 存储的是设备文件 /etc 存储的是系统的配置文件 /root 存储的是root用户的家目录 /hom ... 
- 递归法求组合数C(m,n)
			假设这样一个数组: 1 2 3 4 5 n=5 若 m=3 也就是要求C(3,5) 首先先选第一个数 1 那么剩下的工作就是在2-5之间选择2个数 如果我们没有选择第一个数 选第二个数2 那么剩下的工 ... 
- mysql定时任务/mysql作业
			转自:https://www.jb51.net/article/138569.htm 详细参考:https://www.cnblogs.com/qlqwjy/p/7954175.html(事件& ... 
