题面

CF101D Castle

给一棵 \(n\) 个节点的带权树,求一种遍历方案,从 \(1\) 出发,每条边走两次,走过所有点,第一次经过每个节点的平均时间最小。输出这个平均时间。

数据范围:\(2\le n\le 10^5\)。


题解

可以对于每棵子树单独计算。

虽然子树内走的顺序是不固定的,但是要消耗的总时间是固定的。

设 \(f_u\) 表示 \(u\) 这棵子树内的第一次经过每个节点的 时间和,\(w_{u,v}\) 是 \(u,v\) 两点间的边权,\(sz_u\) 是 \(u\) 的子树大小,\(szt_u\) 是走遍 \(u\) 这棵子树的所需时间。

由于每棵子树遍历一次而且有顺序,记 \(v_i\) 为 \(u\) 第 \(i\) 个遍历的子树。

\[f_u=\sum_{i} [f_{v_i}+sz_{v_i}w_{u,v_i}+(szt_{v_i}+2w_{u,v})\sum_{j>i} sz_{v_j}]
\]

\(\sum_{i} (f_{v_i}+sz_{v_i}w_{u,v_i})\) 是顺序不同时固定的,\(\sum_{i} (szt_{v_i}+2w_{u,v})\sum_{j>i} sz_{v_j}\) 是会变的,所以这题的难点在于找到它的最小值。

蒟蒻想了好久,这个式子很眼熟,但是怎么化都貌似不能贪心,于是请教了旁边的保队长。

很明显,如果对于 \(i\ge 3\),\(v_i\) 都已经确定,那么 \(p\) 和 \(q\) 分别作为 \(v_1,v_2\) 的贡献是

\[v_1=p,v_2=q:(szt_p+2w_{u,p})(sz_{q}+\sum_{j\ge 3} sz_{v_j})+(szt_p+2w_{u,p})\sum_{j\ge 3}sz_{v_j}+\cdots
\]
\[v_1=q,v_2=p:(szt_q+2w_{u,q})(sz_{p}+\sum_{j\ge 3} sz_{v_j})+(szt_q+2w_{u,q})\sum_{j\ge 3}sz_{v_j}+\cdots
\]

其实差别就在于 \((szt_p+2w_{u,p})sz_{q}\) 和 \((szt_q+2w_{u,q})sz_{p}\),而且手玩一下可以发现,对于任意两个 \(v\) 顺序都是类似的。

所以把所有 \(v\in son_u\) 丢进一个 vector,然后对于 \(p\),\(q\),按上面的差别排序即可。


代码

#include <bits/stdc++.h>
using namespace std; //Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair((a),(b))
#define x first
#define y second
#define bg begin()
#define ed end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define R(i,a,b) for(int i=(a),i##E=(b);i<i##E;i++)
#define L(i,a,b) for(int i=(b)-1,i##E=(a)-1;i>i##E;i--)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f; //Data
const int N=1e5;
int n; //Tree
vector<int> e[N],to,we;
void adde(int u,int v,int w){
e[u].pb(sz(to)),to.pb(v),we.pb(w);
e[v].pb(sz(to)),to.pb(u),we.pb(w);
}
int sz[N],szt[N];
ll dfs(int u,int fa){
ll res=0; sz[u]=1,szt[u]=0;
vector<int> cho;
for(int v:e[u])if(to[v]^fa){
res+=dfs(to[v],u);
res+=1ll*we[v]*sz[to[v]];
szt[to[v]]+=we[v]*2;
sz[u]+=sz[to[v]],szt[u]+=szt[to[v]];
cho.pb(to[v]);
}
sort(cho.bg,cho.ed,[&](int p,int q){
return 1ll*szt[p]*sz[q]<1ll*szt[q]*sz[p];
});
int tot=sz[u]-1;
for(int v:cho) tot-=sz[v],res+=1ll*szt[v]*tot;
return res;
} //Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cout.precision(12);
cin>>n;
R(i,1,n){int u,v,w; cin>>u>>v>>w,--u,--v,adde(u,v,w);}
// cout<<dfs(0,-1)<<'\n';
cout<<fixed<<1.*dfs(0,-1)/(n-1)<<'\n';
return 0;
}

祝大家学习愉快!

题解-CF101D Castle的更多相关文章

  1. CF101D Castle 树形DP、贪心

    题目传送门 题意:给出一个有$N$个点的树,你最开始在$1$号点,经过第$i$条边需要花费$w_i$的时间.每条边只能被经过$2$次.求出到达除$1$号点外所有点的最早时间的最小平均值.$N \leq ...

  2. CF101D Castle

    传送门 首先,一定要把所有点遍历一遍,这时答案应该是\(\frac{\sum 某个点第一次被遍历的时间点}{n-1}\quad\),而且每条边只能走两次,所以每次要遍历完某棵子树才能遍历其它子树. 考 ...

  3. 洛谷 P2945 [USACO09MAR]沙堡Sand Castle 题解

    题目传送门 大概思路就是把这两个数组排序.在扫描一次,判断大小,累加ans. #include<bits/stdc++.h> using namespace std; int x,y,z; ...

  4. 题解 洛谷P1457 【城堡 The Castle】

    这道题,看似很烦,无从下手,但其实只要用位运算和联通快就能水过了呀. 首先,输入:似乎大意是把一个数拆成二进数的相加,分别表示\((i,j)\)东南西北是否有墙.\(1\)表示西,\(2\)表示北,\ ...

  5. 题解 P1457 【城堡 The Castle】

    来讨论区大摇大摆地逛了一圈后,我发现竟然大家的代码 都很长 然而代码真的要写那么长吗 首先,来分析问题,1,2,4,8,这些数显然是有特点的,也许你已经想到了没错,它们都是2的次方数. 1是2的0次方 ...

  6. 洛谷P1457 城堡 The Castle

    P1457 城堡 The Castle 137通过 279提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 我们憨厚的USACO ...

  7. BZOJ3399: [Usaco2009 Mar]Sand Castle城堡

    3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 22  Solved: 17[Sub ...

  8. 3399: [Usaco2009 Mar]Sand Castle城堡

    3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 37  Solved: 32[Sub ...

  9. P1457 城堡 The Castle

    轻度中毒 原题 :The Castle 以下为题解部分:明明辣么简单的一道题,硬是搞了1.5h,WTF?以下列出本题的一些要点. 搜索(DFS)嘛,染色嘛,统计大小嘛,很容易想,也很更易处理. 接下来 ...

随机推荐

  1. 四、API Gateway相关------微服务构架设计模式

  2. C/C++中内存对齐问题的一些理解(转)

    内存对齐指令 一般来说,内存对齐过程对coding者来说是透明的,是由编译器控制完成的 如对内存对齐有明确要求,可用#pragma pack(n)指定,以n和结构体中最长数据成员长度中较小者为有效值 ...

  3. OpenCV之图像归一化(normalize)

    什么图像归一化 通俗地讲就是将矩阵的值通过某种方式变到某一个区间内 图像归一化的作用 目前能理解的就是归一化到某个区间便于处理,希望高人可以指点 opencv文档中的介绍 C++: void norm ...

  4. ceph打印出每秒的IO和pg状态

    前言 在ceph 的jewel版本以及之前的版本,通过ceph -w命令是可以拿到每秒钟ceph集群的io状态的,现在的版本是ceph -s一秒秒手动去刷,ceph -w也不监控io的状态了,有的时候 ...

  5. 02、Hibernate开发步骤

    1.创建Hibernate配置文件(hibernate.cfg.xml) <?xml version="1.0" encoding="UTF-8"?> ...

  6. [代码审计Day1] in_array代码审计

    简介 1 简介  in_array() 函数搜索数组中是否存在指定的值. 语法:in_array(search,array,type) 参数 描述 search 必需.规定要在数组搜索的值. arra ...

  7. [web安全原理]PHP反序列化漏洞

    前言 这几天一直在关注新管状病毒,从微博到各大公众号朋友圈了解感觉挺严重的看微博感觉特别严重看官方说法感觉还行那就取中间的吧 自己要会对这个东西要有理性的判断.关注了好两天所以耽搁了学习emmm 希望 ...

  8. 掌握Python可以去哪些岗位?薪资如何?

    一.人工智能 Python作为人工智能的黄金语言,选择人工智能作为就业方向是理所当然的,就业前景也还不错.人工智能工程师的招聘起薪一般在20K-35K,如果是初级工程师,起薪一般12K. 二.大数据 ...

  9. 面试大厂,90%会被问到的Java面试题(附答案)

    面向对象的三个特征 封装,继承,多态 多态的好处,代码中如何实现多态,虚拟机中如何实现多态 允许不同类对象对同一消息作出相应,好处如下: 可替换性:多态对已存在的代码具有可替换性 可扩充性:增加新的子 ...

  10. 03python开发之流程控制

    03 python开发之流程控制 目录 03 python开发之流程控制 3 流程控制 3.1 流程判断之if判断 3.1.1 代码块 3.1.2 if判断基础语法 3.1.3 案例 3.1.4 if ...