【2019 CCPC 江西省赛】Cotree 树重心
时间:2020-10-16
本文章向大家介绍【2019 CCPC 江西省赛】Cotree 树重心,主要包括【2019 CCPC 江西省赛】Cotree 树重心使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题意
给出 \(n\) 个顶点,\(n-2\) 条边。也就是两颗树,现在让连一条边,变成一颗树,使得 \(\sum_{i=1}^{n}\sum_{j=i+1}^{n}dis(i,j)\) 最小。
瞎哔哔
看完题盲猜一波把两棵树的重心连到一起。写起来太麻烦,而且不保证结论正不正确。
就去写了一个等腰梯形的题目,然后由于自己把题意读错,疯狂WA,最后yzj队,把A题一过,跑我们上面去了。
一看他们过,我猜结论应该是正确的。
yzj说就剩一小时了,这题代码挺长的,你们应该过不了了。
一听,这这这。
开始疯狂敲代码,半小时写完,小小的改了一下bug,过了样例,一交过了。
真爽
题解
先求出两颗树的重心,连起来。
如何算这个呢?
\(\sum_{i=1}^{n}\sum_{j=i+1}^{n}dis(i,j)\)
我们枚举边的贡献。
对于每条边边它的贡献为:\(sz[u]*(n-sz[u])\),即左右两边的顶点数量相乘。
代码
/*
* @Autor: valk
* @Date: 2020-08-11 12:38:37
* @LastEditTime: 2020-10-16 13:32:27
* @Description: 如果邪恶 是华丽残酷的乐章 它的终场 我会亲手写上 晨曦的光 风干最后一行忧伤 黑色的墨 染上安详
*/
#include <bits/stdc++.h>
#define fuck system("pause")
#define pb emplace_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
int sz[N], mxsz[N];
vector<int> vec[N];
int vis[N], n, m;
void solve(int u, int fa)
{
++m;
vis[u] = 1;
for (int v : vec[u]) {
if (v == fa || vis[v])
continue;
solve(v, u);
}
}
int dfs(int u, int fa)
{
sz[u] = 1;
for (int v : vec[u]) {
if (v == fa)
continue;
dfs(v, u);
sz[u] += sz[v];
mxsz[u] = max(mxsz[u], sz[v]);
}
if (vis[u] == 0)
mxsz[u] = max(mxsz[u], n - sz[u]);
else
mxsz[u] = max(mxsz[u], m - sz[u]);
}
int dfs1(int u, int fa)
{
sz[u] = 1;
for (int v : vec[u]) {
if (v == fa)
continue;
dfs1(v, u);
sz[u] += sz[v];
}
}
ll rel = 0;
int dfs2(int u, int fa)
{
for (int v : vec[u]) {
if (v == fa)
continue;
rel += 1LL * sz[v] * (n - sz[v]);
dfs2(v, u);
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n - 2; i++) {
int u, v;
scanf("%d%d", &u, &v);
vec[u].pb(v), vec[v].pb(u);
}
solve(1, 1); //染色
n -= m;
int rt1, rt2;
for (int i = 1; i <= n + m; i++) {
if (vis[i] == 1) {
rt1 = i;
break;
}
}
for (int i = 1; i <= n + m; i++) {
if (vis[i] == 0) {
rt2 = i;
break;
}
}
dfs(rt1, rt1);
int minn = inf;
for (int i = 1; i <= n + m; i++) {
if (vis[i] == 1)
minn = min(minn, mxsz[i]);
}
int w1, w2;
for (int i = 1; i <= n + m; i++) {
if (vis[i] == 1 && minn == mxsz[i]) {
w1 = i;
}
}
dfs(rt2, rt2);
minn = inf;
for (int i = 1; i <= n + m; i++) {
if (!vis[i]) {
minn = min(minn, mxsz[i]);
}
}
for (int i = 1; i <= n + m; i++) {
if (vis[i] == 0 && minn == mxsz[i]) {
w2 = i;
}
}
vec[w1].pb(w2), vec[w2].pb(w1);
memset(sz, 0, sizeof(sz));
n += m;
dfs1(1, 1);
dfs2(1, 1);
printf("%lld\n", rel);
return 0;
}
原文地址:https://www.cnblogs.com/valk3/p/13828883.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 关于 Spring Ioc,看这一篇就够了!
- 第1次Spring源码学习之@Bean、@Configuration、xml、分析
- Spring 中的依赖注入(DI),你都知道多少?
- Docker配置1台Nginx+3台Tomcat做负载均衡
- Centos7.x+Docker部署RabbitMQ
- LeetCode(1)-找出数组中重复的数字
- LeetCode(面试题:二维数组中的查找)
- 面试题05-替换空格(LeeCode)
- 解决Mybatis当实体类中的属性名和表中的字段名不一致的问题
- 图书管理系统(一)项目框架结构搭建
- Mybatis中模糊查询like语句的使用方法
- win10暴力查看wifi密码
- 再也不怕面试官问java中的goto关键字了?
- 死磕Java之分析short类型
- 死磕Java之Java数据类型的来龙去脉