zoukankan      html  css  js  c++  java
  • loj10157

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

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

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

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

    Picture1

    输入格式

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

    第一行 n,表示树中结点的数目。

    第二行至第 n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号 i(0<in),在该宫殿安置侍卫所需的经费 k,该边的儿子数 m,接下来 m 个数,分别是这个节点的 m 个儿子的标号r1,r2,,rm

    对于一个 n 个结点的树,结点标号在 1 到 n 之间,且标号不重复。

    输出格式

    输出最少的经费

    数据范围与提示

    对于 100% 的数据,0<n1500。

    ______________________________________________________________________________________________________________________

    f[u][0]:u点由父节点看守

    f[u][1]:u点由子节点看守

    f[u][2]:u点由自己看守

    f[u][0]=sum(min(f[v][1],f[v][2]))

    f[u][2]=sum(min(f[v][0],f[v][1],f[v][2]))+fy[u]

    f[u][1]=sum(min(f[v][1],f[v][2]))+min(f[v][2]-min(f[v][1],f[v][2]))

    注意f[u][1]的推导

    ______________________________________________________________________________________________________________________

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1510;
     4 int n,root;
     5 int fy[maxn],rd[maxn];
     6 struct edge
     7 {
     8     int u,v,nxt;
     9 }e[maxn];
    10 int head[maxn],js;
    11 void addage(int u,int v)
    12 {
    13     e[++js].u=u;e[js].v=v;
    14     e[js].nxt=head[u];head[u]=js;
    15 }
    16 int f[maxn][3];
    17 int minn(int a,int b,int c)
    18 {
    19     int tp=a;
    20     if(tp>b)tp=b;
    21     if(tp>c)tp=c;
    22     return tp;
    23 }
    24 void dp(int u,int fa)
    25 {
    26     f[u][0]=f[u][1]=0;
    27     f[u][2]=fy[u];
    28     int tp=0x7fffffff;
    29     for(int i=head[u];i;i=e[i].nxt)
    30     {
    31         int v=e[i].v;
    32         dp(v,u);
    33         f[u][0]+=min(f[v][1],f[v][2]);
    34         f[u][2]+=minn(f[v][0],f[v][1],f[v][2]);
    35         f[u][1]+=min(f[v][1],f[v][2]);
    36         tp=min(tp,f[v][2]-min(f[v][1],f[v][2]));
    37     }
    38     f[u][1]+=tp;
    39 }
    40 int main()
    41 {
    42     scanf("%d",&n);
    43     for(int u,nm,v,i=1;i<=n;++i)
    44     {
    45         scanf("%d",&u);
    46         scanf("%d%d",&fy[u],&nm);
    47         for(int j=0;j<nm;++j)
    48         {
    49             scanf("%d",&v);
    50             rd[v]++;
    51             addage(u,v);
    52         }
    53     }
    54     for(int i=1;i<=n;++i)
    55     {
    56         if(rd[i]==0)
    57         {
    58             root=i;
    59             break;
    60         }
    61     }
    62     dp(root,0);
    63     cout<<min(f[root][1],f[root][2]);
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    strtok和strtok_r
    几种更新(Update语句)查询的方法
    常见的几种RuntimeException
    初识ASP.NET---若干常见错误
    Microsoft.AlphaImageLoader滤镜解说
    情绪管理--不要总做“好脾气”的人。
    Linux中搭建SVNserver
    Java虚拟机的启动与程序的执行
    Ubuntu下deb包的安装方法
    財哥面京东dm的经历【帮財哥发的】
  • 原文地址:https://www.cnblogs.com/gryzy/p/10149289.html
Copyright © 2011-2022 走看看