HNOI2018 道路

Luogu

真·普及 DP

令 \(f_{x,y,z}\) 为在 \(i\) 点,有 \(y\) 条公路没修,有 \(z\) 条铁路没修

\[f_{x,y,z}=\max{f_{s_i,y+1,z}+f_{t_i,y,z},f_{s_i,y,z}+f_{s_i,y,z+1}}\]

由于树的高是保证的,所以并不会被卡空间

可以先把 \(dfn\) 跑出来后倒着推,也可以直接 \(dfs\)

注意下细节

#include <iostream>
#include <cstdio>
#include <cstring>

typedef long long ll;

const int MaxN = 4e4 + 5;

int N;
int Ch[MaxN][2], A[MaxN], B[MaxN], C[MaxN];
ll Dp[MaxN][41][41];

inline void dfs(int x, int s1, int s2)
{
    if(x >= N)
    {
        for(int i = 0; i <= s1; ++i)
            for(int j = 0; j <= s2; ++j)
                Dp[x][i][j] = 1ll * C[x] * (A[x] + i) * (B[x] + j);
        return;
    }
    dfs(Ch[x][0], s1 + 1, s2);
    dfs(Ch[x][1], s1, s2 + 1);
    for(int i = 0; i <= s1; ++i)
        for(int j = 0; j <= s2; ++j)
            Dp[x][i][j] = std::min(Dp[Ch[x][0]][i + 1][j] + Dp[Ch[x][1]][i][j], Dp[Ch[x][0]][i][j] + Dp[Ch[x][1]][i][j + 1]);
}

int main()
{
    int x, y;
    scanf("%d", &N);
    for(int i = 1; i < N; ++i)
    {
        scanf("%d %d", &x, &y);
        if(x < 0) x = -x + N - 1;
        if(y < 0) y = -y + N - 1;
        Ch[i][0] = x;
        Ch[i][1] = y;
    }
    for(int i = 1; i <= N; ++i)
    {
        x = i + N - 1;
        scanf("%d %d %d" ,&A[x], &B[x], &C[x]);
    }
    dfs(1, 0, 0);
    printf("%lld\n", Dp[1][0][0]);
    return 0;
}

原文地址:https://www.cnblogs.com/zcdhj/p/8886248.html

时间: 2024-10-12 15:30:02

HNOI2018 道路的相关文章

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

题目 题目太长懒得打 题解 HNOI2018惊现普及+/提高? 由最长路径很短,设\(f[i][x][y]\)表示\(i\)号点到根有\(x\)条未修公路,\(y\)条未修铁路,子树所有乡村不便利值的最小值 如果\(i\)为乡村,直接等于公式 如果\(i\)不为乡村,枚举修哪边儿子 \(f[i][x][y] = min\{f[ls][x + 1][y] + f[rs][x][y],f[ls][x][y] + f[rs][x][y + 1]\}\) \(ans = f[1][0][0]\) 很多\

P1070 道路游戏

题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编号为1~n,因为马路是环形的,所以第 n 个机器人工厂和第 1 个机器人工厂是由一段马路连接在一起的.小新将连接机器人工厂的这 n 段马路也编号为 1~n,并规定第 i 段马路连接第 i 个机器人工厂和第 i+1 个机器人工厂(1≤i≤n-1),第 n 段马路连接第 n 个机器人工厂和第 1个机器人

基于单分类器的高分辨率遥感影像道路提取

本人硕士阶段做了很久的高分辨率遥感影像道路提取,颇有心得,在此,本人将最新的研究成果进行开源... 大家都知道,传统的基于机器学习的分类方法通常需要正负样本的同时参与,才能得到目标类,但是负样本的勾选,通常很困难,也非常难获得,根据文献- <Elkan, Charles, and Keith Noto. "Learning classifiers from only positive and unlabeled data." Proceedings of the 14th ACM

【Codevs1183】泥泞的道路

Position: http://codevs.cn/problem/1183/ List Codevs1183 泥泞的道路 List Description Input Output Sample Input Sample Output HINT Solution Code Description CS有n个小区,并且任意小区之间都有两条单向道路(a到b,b到a)相连.因为最近下了很多暴雨,很多道路都被淹了,不同的道路泥泞程度不同.小A经过对近期天气和地形的科学分析,绘出了每条道路能顺利通过的

POJ 2421 Constructing Roads 修建道路 最小生成树 Kruskal算法

题目链接:POJ 2421 Constructing Roads 修建道路 Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19698   Accepted: 8221 Description There are N villages, which are numbered from 1 to N, and you should build some roads such that e

【bzoj1579/Usaco2009 Feb】Revamping Trails 道路升级——分层图最短路

题目链接 建立0~k共k+1层图,用dis[x][d]表示x到源点(此题为1)将d条道路距离降为0的距离,dijkstra跑的话因为从堆顶取出的就是已经确定的,因此当从堆顶取出的元素是n时,就可以直接返回并输出了. 用了堆优化,注意每次从堆顶取出元素后如果p.w!=dis[p.to][p.d],说明这条路径所到达的点到源点的路径已经被其他路径所松弛,换句话说,此时1~x走的根本不是存的这条路径,所以要重新从堆顶取满足条件的元素. 1 #include<cstdio> 2 #include<

找地图上道路不连通的地方(考虑通行方向)

实现算法 1.首先将满足条件的道路(link) 放到指定的容器中 vector<sdk::link> vec_linkA; vector<sdk::link> vec_linkB;     //同时copy一份到vec_linkB vector<sdk::link> vec_link_error; //存放不通地方的道路也就是link 2.将vec_linkB 的link逐一出栈去vec_linkA查找是否有该link下一条可行的路,只要能找到一条就证明这里是通的 a.

奇怪的道路(状压)

[Jxoi2012]奇怪的道路 时间限制: 1 Sec  内存限制: 128 MB提交: 55  解决: 23[提交][状态][讨论版] 题目描述 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往.一对城市之间可能存在多条道路.据史料记载,这个文明的交通网络满足两个奇怪的特征.首先,这个文明崇拜数字K,所以对于任何一

奇怪的道路

问题 A: [Jxoi2012]奇怪的道路 题目描述 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往.一对城市之间可能存在多条道路.据史料记载,这个文明的交通网络满足两个奇怪的特征.首先,这个文明崇拜数字K,所以对于任何一条道路,设它连接的两个城市分别为u和v,则必定满足1 <=|u - v| <= K.此外,任