题目传送门

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


设$f_i$表示以第$i$个点为子树的最小总时间,考虑由儿子向父亲合并,额外定义$dis_i$为$i$到其父亲的边的边权,$t_i$表示从$t$的父亲走完根节点为$t$的子树再回到$t$的时间,也就等于$(\text{子树边权和+与父亲相连的边的边权})\times 2$,再定义$size_i$表示以$i$为根节点的子树的点数。可以$t_i$与$size_i$都是很容易从儿子向父亲合并的。

设我们正在算点$x$的答案,其儿子为$y_1,y_2...y_k$,且它们的答案已经算出来了。那么它的父亲的答案也就是$\sum\limits_{i=1}^k (f_{y_i}+dis_i \times size_i) + \sum\limits_{i=1}^k t_{p_i} \times (size_x - 1 - \sum\limits_{j=1}^i size_{p_i})$,其中$p_1,p_2...p_k$是一个$y_1,y_2...y_k$的排列,因为子树的选择是无序的,而在选择某个子树的时候,剩下没有选的所有点都需要等待这棵子树遍历完。

那么现在我们的任务转变为了找到一个最优的$p_1,p_2...p_k$的选择。考虑这个排列可能与排序有关,所以我们使用邻项交换的方法分析是否具有贪心策略。考虑相邻两个元素$p_i,p_i+1$,因为交换对于其他元素的答案是没有影响的,所以我们只需要考虑$p_i$与$p_{i+1}$的差别,将其他的设为$W$。

当我们的顺序是$p_i,p_{i+1}$时,答案是$f_{p_i}+t_{p_i} \times size_{p_{i+1}}+f_{p_{i+1}}+W$,而当顺序为$p_{i+1},p_i$时答案为$f_{p_{i+1}}+t_{p_{i+1}} \times size_{p_i}+f_{p_i}+W$。我们令第一种方案优于第二种方案,所以$f_{p_i}+t_{p_i} \times size_{p_{i+1}}+f_{p_{i+1}}+W < f_{p_{i+1}}+t_{p_{i+1}} \times size_{p_i}+f_{p_i}+W$,可以得到$t_{p_i} \times size_{p_{i+1}} < t_{p_{i+1}} \times size_{p_i}$。所以我们使用这个公式进行排序,就可以得到最优的方案。

 #include<bits/stdc++.h>
 #define ld long double
 #define MAXN 500010
 #define int long long
 using namespace std;

 inline int read(){
     ;
     ;
     char c = getchar();
     while(!isdigit(c)){
         if(c == '-')
             f = ;
         c = getchar();
     }
     while(isdigit(c)){
         a = (a << ) + (a << ) + (c ^ ');
         c = getchar();
     }
     return f ? -a : a;
 }

 struct Edge{
     int end , upEd , w;
 }Ed[MAXN];
 int head[MAXN] , siz[MAXN] , T[MAXN] , N , cntEd , forC;
 ld dp[MAXN];

 bool cmp(int a , int b){
     return T[a] * siz[b] < T[b] * siz[a];
 }

 inline void addEd(int a , int b , int c){
     Ed[++cntEd].end = b;
     Ed[cntEd].upEd = head[a];
     Ed[cntEd].w = c;
     head[a] = cntEd;
 }

 void dfs(int now){
     siz[now] = ;
     vector < int > v;
     for(int i = head[now] ; i ; i = Ed[i].upEd)
         if(!siz[Ed[i].end]){
             dfs(Ed[i].end);
             siz[now] += siz[Ed[i].end];
             T[Ed[i].end] += Ed[i].w << ;
             dp[Ed[i].end] += Ed[i].w * siz[Ed[i].end];
             v.push_back(Ed[i].end);
         }
     sort(v.begin() , v.end() , cmp);
      ; i < v.size() ; i++){
         dp[now] += T[now] * siz[v[i]] + dp[v[i]];
         T[now] += T[v[i]];
     }
 }
 main(){
     N = read();
      ; i < N ; i++){
         int a = read() , b = read() , c = read();
         addEd(a , b , c);
         addEd(b , a , c);
     }
     dfs();
     cout << ) << dp[] * );
     ;
 }

CF101D Castle 树形DP、贪心的更多相关文章

  1. 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心

    题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...

  2. [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)

    传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...

  3. bzoj 3829: [Poi2014]FarmCraft 树形dp+贪心

    题意: $mhy$ 住在一棵有 $n$ 个点的树的 $1$ 号结点上,每个结点上都有一个妹子. $mhy$ 从自己家出发,去给每一个妹子都送一台电脑,每个妹子拿到电脑后就会开始安装 $zhx$ 牌杀毒 ...

  4. 树形DP+贪心(乱搞)(HDU4714)

    题意:给出一个树形图,要求把该树形成一个环最少的步骤(断开一条边和形成一条边都需一步) 分析:很明显,要想把树形成一个环,就要先把其分裂成m条子链之后把子链形成环需要的步骤是2*m+1,所以只需要m最 ...

  5. [HNOI2003]消防局的设立 树形dp // 贪心

    https://www.luogu.org/problemnew/show/P2279 一开始就想到了贪心的方法,不过一直觉得不能证明. 贪心的考虑是在深度从深到浅遍历每个结点的过程中,对于每个没有覆 ...

  6. POJ - 2057 The Lost House(树形DP+贪心)

    https://vjudge.net/problem/POJ-2057 题意 有一只蜗牛爬上某个树枝末睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面,.现在这只蜗牛要求寻找 ...

  7. [POI2014]FAR-FarmCraft 树形DP + 贪心思想

    (感觉洛谷上题面那一小段中文根本看不懂啊,好多条件都没讲,直接就是安装也要一个时间啊,,,明明不止啊!还好有百度翻译......) 题意:一棵树,一开始在1号节点(root),边权都为1,每个点有点权 ...

  8. ACM学习历程—FZU2195 检查站点(树形DP || 贪心)

    Description 在山上一共有N个站点需要检查,检查员从山顶出发去各个站点进行检查,各个站点间有且仅有一条通路,检查员下山前往站点时比较轻松,而上山时却需要额外的时间,问最后检查员检查完所有站点 ...

  9. BZOJ4027/LG4107 「HEOI2015」兔子与樱花 树形DP+贪心

    问题描述 LG4107 题解 首先,我们可以直接令结点 \(x\) 的权值为 \(c[x]+son_x\) ,发现将 \(x,y\) 合并,相当于增加 \(c[x]+c[y]-1\) 的重量. 容易想 ...

随机推荐

  1. mysql5.7 安装和多源复制实践

    MySQL 5.7发布后,在复制方面有了很大的改进和提升.比如开始支持多源复制(multi-source)以及真正的支持多线程复制了.多源复制可以使用基于二进制日子的复制或者基于事务的复制.下面我们说 ...

  2. LyX快捷键管理

    快捷键修改:Tools->Preference->Editing->Shortcuts:修改后要Tools->Reconfig生效 快捷键默认保存文件:%appdata%\Ly ...

  3. 9.4、__del__、__doc__、__dict__、__module__、__getitem__、__setitem__、__delitem__、__str__、__repr__、__call__

    相关内容: __del__.__doc__.__dict__.__module__.__getitem__.__setitem__.__delitem__.__str__.__repr__.__cal ...

  4. 配置文件读取工具类--PropertiesUtil

    /** * 属性工具类 * @author admin * 参考:https://www.cnblogs.com/doudouxiaoye/p/5693454.html */ public class ...

  5. [20170623]利用传输表空间恢复部分数据.txt

    [20170623]利用传输表空间恢复部分数据.txt --//昨天我测试使用传输表空间+dblink,上午补充测试发现表空间设置只读才能执行impdp导入原数据,这个也很好理解.--//这样的操作模 ...

  6. The Art of Unit Testing With Examples in .NET

    The Art of Unit Testing With Examples in .NET

  7. Activiti工作流的定义部署和执行

        工作流引擎 个人觉得直接理解工作流引擎概念有点难度,我们可以先通过了解工作流引擎的职责再反过来理解工作流引擎,工作流引擎一般都做两件事情: 1.定义流程,也就是给我们提供某种规范来定义规则,以 ...

  8. 控件_AnalogClock

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  9. Django的settings配置

    静态文件 STATIC_URL = '/static/' # 别名 STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static'), os.path.join ...

  10. centos7下安装docker(12.5容器在单个host上的网络总结)

    单个host上的容器的网络:通过本章的学习,我们知道docker默认有三种网络,可以通过docker network ls查看: none:封闭的网络,通过--network=none来指定: hos ...