问题描述

W 国的交通呈一棵树的形状。W 国一共有n - 1个城市和n个乡村,其中城市从1到n - 1 编号,乡村从1到n编号,且1号城市是首都。道路都是单向的,本题中我们只考虑从乡村通往首都的道路网络。对于每一个城市,恰有一条公路和一条铁路通向这座城市。对于城市i, 通向该城市的道路(公路或铁路)的起点,要么是一个乡村,要么是一个编号比ii大的城市。 没有道路通向任何乡村。除了首都以外,从任何城市或乡村出发只有一条道路;首都没有往 外的道路。从任何乡村出发,沿着唯一往外的道路走,总可以到达首都。

W 国的国王小 W 获得了一笔资金,他决定用这笔资金来改善交通。由于资金有限,小 W 只能翻修n - 1条道路。小 W 决定对每个城市翻修恰好一条通向它的道路,即从公路和铁 路中选择一条并进行翻修。小 W 希望从乡村通向城市可以尽可能地便利,于是根据人口调 查的数据,小 W 对每个乡村制定了三个参数,编号为ii的乡村的三个参数是ai,bi和ci。假设 从编号为i的乡村走到首都一共需要经过x条未翻修的公路与y条未翻修的铁路,那么该乡村 的不便利值为

\[c_i \cdot (a_i + x) \cdot (b_i + y)
\]

在给定的翻修方案下,每个乡村的不便利值相加的和为该翻修方案的不便利值。 翻修n - 1条道路有很多方案,其中不便利值最小的方案称为最优翻修方案,小 W 自然 希望找到最优翻修方案,请你帮助他求出这个最优翻修方案的不便利值。

输入格式

第一行为正整数n。

接下来n - 1行,每行描述一个城市。其中第i行包含两个数si,ti。si表示通向第i座城市 的公路的起点,ti表示通向第i座城市的铁路的起点。如果si > 0,那么存在一条从第si座城 市通往第i座城市的公路,否则存在一条从第-si个乡村通往第i座城市的公路;ti类似地,如 果ti >,那么存在一条从第ti座城市通往第i座城市的铁路,否则存在一条从第-ti个乡村通 往第i座城市的铁路。

接下来n行,每行描述一个乡村。其中第i行包含三个数ai,bi,ci,其意义如题面所示。

输出格式

输出一行一个整数,表示最优翻修方案的不便利值。

样例输入

6

2 3

4 5

-1 -2

-3 -4

-5 -6

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

样例输出

54

解析

由题目的意思,最后构成的树有这些特征:叶节点都是乡村;每个城市只有两个儿子,且一个是公路,一个是铁路。考虑阶段为当前到了哪个点。描述一个状态则需要知道经过了多少公路,多少铁路。所以,我们设计状态如下:

设\(f[x][l][r]\)表示当前在x点,经过了l条未翻修的公路、r条未翻修的铁路的最小不方便值。考虑到正着并不好推,我们尝试着倒着推。每个点只会被两个子节点更新,且一个子节点是经过公路,一个是经过铁路。不难得到,我们有如下方程:

\[f[x][l][r]=min(f[ls[x]][l+1][r],f[rs[x]][l][r+1])
\]

当x为叶节点时,由题中的式子,我们可以得到如下初始状态:

\[f[x][l][r]=c_i*(a_i+l)*(b_i+r)
\]

在dfs时,为了优化时间,我们需要记下当前最多会经过多少条没有翻修的公路和铁路。但是,这并不能解决空间的问题。可以发现,每次结束递归的点此后都不会再调用,所以我们可以每次给一个点一个编号,结束递归回收利用编号,就可以做到优化空间了。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
#define N 40002
using namespace std;
int n,i,a[N],b[N],c[N],ls[N],rs[N],f[102][42][42],dfn[N];
int read()
{
char c=getchar();
int w=0,f=1;
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w*f;
}
void dfs(int x,int l,int r,int tim)
{
dfn[x]=tim;
if(x>=n){
for(int i=0;i<=l;i++){
for(int j=0;j<=r;j++) f[dfn[x]][i][j]=c[x]*(a[x]+i)*(b[x]+j);
}
return;
}
dfs(ls[x],l+1,r,tim+1);
dfs(rs[x],l,r+1,tim+2);
int pl=dfn[ls[x]],pr=dfn[rs[x]];
for(int i=0;i<=l;i++){
for(int j=0;j<=r;j++){
f[dfn[x]][i][j]=min(f[pl][i][j]+f[pr][i][j+1],f[pl][i+1][j]+f[pr][i][j]);
}
}
}
signed main()
{
n=read();
for(i=1;i<=n-1;i++){
ls[i]=read(),rs[i]=read();
if(ls[i]<0) ls[i]=-ls[i]+n-1;
if(rs[i]<0) rs[i]=-rs[i]+n-1;
}
for(i=n;i<=2*n-1;i++) a[i]=read(),b[i]=read(),c[i]=read();
memset(f,0x3f,sizeof(f));
dfs(1,0,0,1);
printf("%lld\n",f[1][0][0]);
return 0;
}

反思

  • 没有看到路径长度小于等于40的条件,导致半天没有设计状态的思路。
  • 正难则反,老是想着从上到下,没有想过可以从叶节点出发倒推得到答案。

[洛谷P4438] HNOI2018 道路的更多相关文章

  1. 洛谷4438 [Hnoi2018]道路 【树形dp】

    题目 题目太长懒得打 题解 HNOI2018惊现普及+/提高? 由最长路径很短,设\(f[i][x][y]\)表示\(i\)号点到根有\(x\)条未修公路,\(y\)条未修铁路,子树所有乡村不便利值的 ...

  2. 洛谷 P5019 铺设道路

    题目描述 春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度 ...

  3. 洛谷P4438 [HNOI/AHOI2018]道路(dp)

    题意 题目链接 Sol 每当出题人想起他出的HNOI 2018 Day2T3,他都会激动的拍打着轮椅 读题比做题用时长系列... \(f[i][a][b]\)表示从根到\(i\)的路径上,有\(a\) ...

  4. 洛谷P4438 道路 [HNOI/AHOI2018] 树形dp

    正解:树形dp 解题报告: 传送门! 昂首先看懂题目趴QwQ大概就是说有棵满二叉树,有n个叶子节点(乡村)和n-1个非叶子节点,然后这棵树的每个节点有三个属性abc,对每个非叶子节点可以从与子节点的两 ...

  5. [NOIP2014] 提高组 洛谷P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  6. NOIP2014 day2 T2 洛谷P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  7. 洛谷 P1272 重建道路 解题报告

    P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...

  8. 洛谷 P2505 [HAOI2012]道路 解题报告

    P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...

  9. 洛谷P3639 [APIO2013] 道路费用 [生成树的特殊算法]

    题目传送门 道路费用 格式难调,题面就不放了. 分析: 这是一道要细(yan)心(jing)的生成树的好(gui)题. 首先我们看到$k$的范围非常小,那么我们就可以直接$2^k$枚举每一条加边是否选 ...

随机推荐

  1. RocketMQ 主从同步

    RocketMQ 的主和从一直在使用 nio 进行数据同步: master master 监听端口 org.apache.rocketmq.store.ha.HAService.AcceptSocke ...

  2. 自动爬取代理IP例子

    import time import json import datetime import threading import requests from lxml import etree from ...

  3. 《Using Python to Access Web Data》Week4 Programs that Surf the Web 课堂笔记

    Coursera课程<Using Python to Access Web Data> 密歇根大学 Week4 Programs that Surf the Web 12.3 Unicod ...

  4. 【FICO系列】SAP ABAP&FI FI/CO接口:待更新的不一致的FI/CO凭证标题数据

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP ABAP&FI ...

  5. unity让碰撞只发生一次

    碰撞发生在帧的开始,所以你可以检测到冲突,并在LateUpdate复位: private bool hasCollided = false; void OnCollisionEnter(Collisi ...

  6. express中app.use()使用方法

    app.use([path,] function [, function…]) 在path上安装中间件,如果path没有被设定,那么默认为”/”. 当为路由设置一个匹配路径后,路由会匹配该路径及该路径 ...

  7. 配置DHCP中继

    本实验模拟企业网络场景.某公司分部的网络由交换机S1和网关路由器R1组成,员工终端PC-1和PC-2都连接在S1上.公司要求分部内所有员工主机的IP地址都通过总部的DHCP服务器自动获取.分部网关路由 ...

  8. webpack4下url-loader打包图片问题

      webpack.condig.js: const path = require('path'); //导入插件 const VueLoaderPlugin = require('vue-loade ...

  9. 基于webstorm卡顿问题的2种解决方法

    基于webstorm卡顿问题的2种解决方法:https://www.jb51.net/article/128441.htm

  10. (Windows)Python第三方库手动安装教程(以lxml库为例)

    案例前提:已安装Python 已安装pip 1.进入官网https://www.lfd.uci.edu/~gohlke/pythonlibs/,搜索lxml库,下载到本地(放到Python目录下的Sc ...