Joy OI【走廊泼水节】题解--最小生成树推论变式
题目链接:
思路:
首先这需要一个推论:
“给定一张无向图,若用\(k(k<n-1)\)条边构成一个生成森林(可以理解为多个互不相通的生成树),再从剩下的\(m-k\)条边中选出\(n-1-k\)条边构成改该图的最小生成树,则这\(m-k\)条边中一定包含连接两个不相连生成森林的最小边权的两点”
这个推论是由这个定理得到:
“一张无向图的最小生成树一定包含边权最小的那条边”,这个定理可以很容易地用反证法证得。
那么我们就可以开始了,若连接两个不连通的生成森林最小边权为\(e\),根据推论,想要让它变成一张完全图而最小生成树保持不变,当然是让剩下的点相连边的权值为\(e+1\)。
那么让这两个生成森林变成完全图则需要\((e+1)*(size[A]*size[B]-1)\),\(size[K]\)为以K为父节点的生成森林所含的点数,减去1是因为两个之中已经有一条边权为\(e\)的边
根据贪心的思想,我们显然所有边从小到大排序,如果两顶点不在一个森林里,那么合并,加入贡献。
代码(话说并查集路径压缩一开始写错了,查了好久的错,真是太蒻了):
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <queue>
#include <vector>
#define ll long long
#define ri register int
using namespace std;
const int maxn=6005;
const int inf=0xfffffff;
struct Edge{
int f,t,val;
bool operator <(const Edge &b)const{
return val<b.val;
}
}edge[maxn];
int n,t;
ll ans=0;
int size[maxn],fa[maxn];
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
int get(int x){
if(fa[x]!=x)fa[x]=get(fa[x]);
return fa[x];//注意路径压缩写法
}
int main(){
int u,v,d;
read(t);
while(t--){
int ans=0;
memset(edge,0,sizeof(edge));
read(n);
for(ri i=1;i<n;i++)
read(edge[i].f),read(edge[i].t),read(edge[i].val);
sort(edge+1,edge+n);
for(ri i=1;i<=n;i++){fa[i]=i,size[i]=1;}
for(ri i=1;i<n;i++){
u=edge[i].f,v=edge[i].t,d=edge[i].val;
//cout<<u<<' '<<v<<endl;
u=get(u),v=get(v);
//cout<<u<<' '<<v<<endl;
if(u!=v){
fa[u]=v;
ans+=(d+1)*(size[u]*size[v]-1);
size[v]+=size[u];
}
}
printf("%d\n",ans);
}
return 0;
}
Joy OI【走廊泼水节】题解--最小生成树推论变式的更多相关文章
- CH6201 走廊泼水节【最小生成树】
6201 走廊泼水节 0x60「图论」例题 描述 [简化版题意]给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树.求增加的边的权值总和最小是多少. 我 ...
- [Tvvj1391]走廊泼水节(最小生成树)
[Tvvj1391]走廊泼水节 Description 给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树.求增加的边的权值总和最小是多少. 完全图:完 ...
- tyvj 1391 走廊泼水节【最小生成树】By cellur925
题目传送门 题意简化:给你一棵树,要求你加边使它成为完全图(任意两点间均有一边相连) ,满足原来的树是这个图的最小生成树.求加边的价值最小是多少. 考虑Kruskal的过程,我们每次找一条最短的,两边 ...
- AcWing 走廊泼水节 题解
这道题大致题意就是让一棵树任意两点有连边(也就是完全图),但是补完后最小生成树是一开始的那棵树,问最小加的边权之和是多少. 了解题意后,我们可以想到用Kruskal(废话),当每两个集合合并的时候,除 ...
- acwing346 走廊泼水节 (最小生成树)
完全图就是每两个点都有直接相连的边. 模拟Kruskal算法的过程,每选择一条边加入时,他两端端点在同一个集合中就跳过,否则考虑合并两个集合,合并时需要增加的每条边的权值至少是edge[i]+1,这才 ...
- CH 6201 走廊泼水节题解
题目链接:CH6201 当时在海亮考试的第一题: 心得:其实一个算法是要真正理解这个思路和过程,而并不是单单知道它是用来写什么题的: 思路:n个节点有n-1条边,把这n-1条边按照权值从小到大排序,有 ...
- SP338ROADS题解--最短路变式
题目链接 https://www.luogu.org/problemnew/show/SP338 分析 联想到不久前做过的一道题\(Full\) \(Tank\),感觉可以用优先队列做,于是写了\(d ...
- 「CH6201」走廊泼水节
「CH6201」走廊泼水节 传送门 考虑 \(\text{Kruskal}\) 的过程以及用到一个最小生成树的性质即可. 在联通两个联通块时,我们肯定会选择最小的一条边来连接这两个联通块,那么这两个联 ...
- 一道令人抓狂的零一背包变式 -- UVA 12563 Jin Ge Jin Qu hao
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
随机推荐
- vue-cli及vue-router
1.单文件组件 (1)问题: 使用 Vue.component 来定义全局组件,紧接着用 new Vue({ el: ‘#container ‘}) 在每个页面内指定一个容器元素.当在更复杂的项 ...
- Animator动画XML实现
在res下创建文件夹animator文件夹 <?xml version="1.0" encoding="utf-8"?> <objectAni ...
- js实现两个文本框数值的加减乘除运算
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_01-用户认证-用户认证流程分析
1 用户认证 1.1 用户认证流程分析 用户认证流程如下: 访问下面的资源需要携带身份令牌和jwt令牌,客户端可以通过身份认证的令牌从服务端拿到长令牌, 一会要实现认证服务请求用户中心从数据库内来查询 ...
- SpringCloud学习成长之路七 高可用配置中心
上一篇文章讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如 ...
- C#反射回顾笔记
一 .反射概述 反射提供描述程序集.模块和类型的对象(Type 类型). 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问其字段和属性. 如果代码中 ...
- MySQL复制表结构
示例SQL: create table testdb.test_table_back like testdb.test_table
- fastJson工具类
jar:fast.jar 依赖: <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId&g ...
- (1)、JEasyUI 之 Datagrid的Combobox 显示 textField 值的问题
(1).JEasyUI 之datagrid的Combobox显示textField值的问题 官方的datagrid Demo Row Editing in DataGrid 中field 是否如下定义 ...
- 【VS开发】【数据库开发】libevent简单入门和介绍
libevent是一个基于事件触发的网络库,memcached底层也是使用libevent库,今天学习下. 总体来说,libevent有下面一些特点和优势: * 统一数据源, 统一I/O事件,信号和定 ...