20181011模拟赛 赛后处刑

今天T1T3巨难写
然而考完一问发现他们并不这么想,心态直接崩了

最小边权和

神题之一
【问题描述】
给你一棵带边权的树,这棵树是某个完全图唯一的最小生成树。问原来的完
全图中所有边可能的最小边权和是多少。完全图是任意两个点之间都有边相连
的图。
【输入格式】
输出第一行包含一个整数 T 表示数据组数。
每组数据第一个整 N 表示点数。
接下来 N − 1 行,每行三个整数 ai, bi, wi,表示最小生成树上 ai 和 bi 之间
有一条权值为 wi 的边。
【输出格式】
输出 T 行,每行表示一组数据的答案。
【样例输入】
2
3
1 2 4
2 3 7
4
1 2 1
1 3 1
1 4 2
【样例输出】
19
12
【数据规模与约定】
对于 20% 的数据,有 T ≤ 5, N ≤ 5, wi ≤ 5
对于另外 30% 的数据,有 N ≤ 1000,给定的树是一条链
对于 100% 的数据,有 T ≤ 10, N ≤ 20000, wi ≤ 10000

这道题提供了一种思路
即用每条边对其所连的联通块产生的影响来统计答案

50%的数据可以直接枚举点对,找链接两点的树链上最大的边

我们思考30%的数据,把一条链上的一条边单独拿出来,左边的点与右边的点(包括边上的两个点)构成的树链一定经过该边,经过树链的个数为左边所有的点*右边所有的点-1(-1是指去除该边的影响),将其看做联通块然后扩展到正常的树,我们就可以统计该边对答案的贡献了

然而这时有前提的,该边对答案造成影响当且仅当该边是两个联通块的所有边中最大的,显然我们只需将边权从小到大排序即可保证新加入的点一定有贡献,再用并查集维护联通块即可
答案统计:
ans+=(size[fu]*size[fv]-1)*(e[i].w+1);
ans+=MST;

以下是没有什么卵用的东西
我们发现
把-1拿出来
ans+=(size[fu]*size[fv])*(e[i].w+1)-1-Σ(i=1,i
Σ(i=1,i
所以
ans+=(size[fu]*size[fv])*(e[i].w+1)-1
好像真的没什么卵用

#include
#include
#include
#include
typedef unsigned long long ull;
int const maxn=20100,maxm=20099;
struct RE
{
	int u,v,w;
}e[maxm];
int cmp(RE x,RE y)
{
	return x.w

你可能感兴趣的:(模拟赛处刑,愚蠢的自己,题解)