「一本通 5.2 例 5」皇宫看守

题目描述

太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。

皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状,某些宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。

可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。

帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

输入格式

输入中数据描述一棵树,描述如下:

第一行

,表示树中结点的数目。

第二行至第

行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号 ,在该宫殿安置侍卫所需的经费 ,该边的儿子数 ,接下来 个数,分别是这个节点的 个儿子的标号

对于一个

个结点的树,结点标号在 到

之间,且标号不重复。

输出格式

输出最少的经费

样例

样例输入

6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0

样例输出

25

样例解释

有六个区域被安排的情况如左图所示。

如右图,灰色点安排了警卫,

号警卫可以观察 , 号警卫可以观察 , 号警卫可以观察

总费用:

数据范围与提示

对于

的数据,

显示分类标签

一道覆盖点的题

dp[u][0] 表示u由父节点覆盖

dp[u][1] 表示u由儿子覆盖

dp[u][2] 表示u由自己覆盖

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;

const int maxn = 1505;

int n,cost[maxn],head[maxn],size,dp[maxn][3],ru[maxn];

struct edge{
    int v,nex;
}e[maxn<<1];

void adde(int u,int v){
    e[size].v=v;e[size].nex=head[u];head[u]=size++;
}

void dfs(int u,int fa){
    //if(ru[u]==1) return ;
    int d=inf;
    dp[u][2]=cost[u];
    for(int i=head[u];~i;i=e[i].nex){
        int v=e[i].v;
        if(v == fa) continue;
        dfs(v,u);
        dp[u][0]+=min(dp[v][1],dp[v][2]);
        dp[u][1]+=min(dp[v][1],dp[v][2]);d=min(d,dp[v][2]-min(dp[v][2],dp[v][1]));//最精髓的转化
        dp[u][2]+=min(dp[v][0],min(dp[v][1],dp[v][2]));
    }
    dp[u][1]+=d;
}

int main(){
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int u,t;scanf("%d",&u);
        scanf("%d%d",&cost[u],&t);
        for(int j=1;j<=t;j++){
            int v;scanf("%d",&v);adde(u,v);adde(v,u);ru[u]++,ru[v]++;
        }
        if(t==0) dp[u][0]=0,dp[u][1]=dp[u][2]=cost[u];
    }
    dfs(1,-1);
    printf("%d",min(dp[1][1],dp[1][2]));
}

原文地址:https://www.cnblogs.com/plysc/p/10579638.html

时间: 2024-09-28 04:16:56

「一本通 5.2 例 5」皇宫看守的相关文章

10249「一本通 1.3 例 5」weight

#10249「一本通 1.3 例 5」weight 题目描述 原题来自:USACO 已知原数列a1,a2,...,an中的前1项,前2项,前3项,... ,前 n 项的和,以及后 1 项,后 2 项,后 3 项,...,后 n 项的和,但是==所有的数都被打乱了顺序==.此外,我们还知道数列中的数存在于集合 S 中.试求原数列.当存在多组可能的数列时,求字典序最小的数列. 输入格式 第 1 行,一个整数 n . 第 2 行, 2 × n 个整数,注意:数据已被打乱. 第 3 行,一个整数 m ,

「一本通 4.2 例 2」最敏捷的机器人(loj10120)

题目描述 Wind 设计了很多机器人.但是它们都认为自己是最强的,于是,一场比赛开始了-- 机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛.首先,他们面前会有一排共 n 个数,它们比赛看谁能最先把每连续 k 个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快. 但是 Wind 也想知道答案,你能帮助他吗? 输入格式 第一行为 n,k,意义如题目描述. 第二行共 n 个数,为数字序列,所有数字均在 Pascal 的 longint 范围内,即所有数均为整数,且

#10114 「一本通 4.1 例 2」数星星 Stars

1536:[例 2]数星星 Stars 时间限制: 256 ms         内存限制: 65536 KB提交数: 630     通过数: 282 [题目描述] 原题来自:Ural 1028 天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标.如果一个星星的左下方(包含正左和正下)有 kk 颗星星,就说这颗星星是 kk 级的. 例如,上图中星星 55 是 33 级的(1,2,41,2,4 在它左下),星星 2,42,4 是 11 级的.例图中有 11 个 00 级,22 个 11 

#10115 「一本通 4.1 例 3」校门外的树

1537:[例 3]校门外的树 时间限制: 1000 ms         内存限制: 524288 KB提交数: 497     通过数: 216 [题目描述] 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两种操作: K=1K=1,读入 l,rl,r 表示在 ll 到 rr 之间种上一种树,每次操作种的树的种类都不同: K=2K=2,读入 l,rl,r 表示询问 ll 到 rr 之间有多少种树. 注意:每个位

#10034.「一本通 2.1 例 2」图书管理-哈希(双哈希思想)+邻接表

样例 样例输入 4 add Inside C# find Effective Java add Effective Java find Effective Java 样例输出 no yes 数据范围与提示 n<=30000 1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 using namespace std; 6 typedef

loj10143. 「一本通 4.6 例 1」营业额统计

思路: 使用treap在线存数据,每次取出新读入数据的前驱与后继,与该数据差值较小的就是.(注意若已有同一个数据,特判ans+=0) #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; const int maxn = 100010; inline void qread(int &x) { x = 0; register

loj10147. 「一本通 5.1 例 1」石子合并

思路: 经典的区间dp,题解到处都是... #include<cstdio> #include<iostream> #include<cstdio> using namespace std; const int maxn = 1010; inline void qread(int &x){ x = 0; register int ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); w

loj10164. 「一本通 5.3 例 2」数字游戏

思路: 既然是数位dp,先写两个函数分别求一个十进制数值的指定位和该数的位数. 设f[i][j]为用i个数字单调不降地填满j个位置,初始化f[i][0]=1(i从1到10),转移方程f[i][j] = . 然后按定义累加即可. #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<cmath> using namespace std; con

loj10193. 「一本通 6.1 例 1」序列的第 k 个数

思路: 简单地快速幂一下就完了. #include<cstdio> #include<iostream> using namespace std; const long long mod = 200907; long long quickpow(long long a, long long b, long long p){ long long res = 1; while(b){ if(b & 1) res = res * a % p; a = a * a % p; b &