• 一本通1579【例 5】皇宫看守


    1579: 【例 5】皇宫看守

    时间限制: 1000 ms         内存限制: 524288 KB

    题目描述

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

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

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

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

    Picture1

    输入格式

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

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

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

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

    输出格式

    输出最少的经费

    样例

    样例输入

    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

    样例解释

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

    如右图,灰色点安排了警卫,2 号警卫可以观察 1,2,5,633 号警卫可以观察 1,3,4 号警卫可以观察 1,4。

    总费用:16+5+4=25

    Picture2 Picture3

    数据范围与提示

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

    sol:这道题我开始看成了没有上司的舞会,GG了无数发后发现它观察的是点(那道题是边)

    dp[x][0,1][0,1]表示那个点是否有哨兵,是否安全,然后暴力转移就ojbk了(其实dp[1][0]是不存在的,其实就三个)

    #include <bits/stdc++.h>
    using namespace std;
    inline int read()
    {
        int s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-');
            ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48);
            ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(long long x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');
            return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    inline void writeln(int x)
    {
        write(x);
        putchar('
    ');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) writeln(x)
    const int N=1505,M=3005,inf=0x3f3f3f3f;
    int n,Cost[N];
    struct Tree
    {
        int tot,Next[M],to[M],head[N];
        inline void add(int x,int y)
        {
            Next[++tot]=head[x];
            to[tot]=y;
            head[x]=tot;
            return;
        }
        long long dp[N][2][2];
        //第一维[0,1]表示这个点是否有士兵
        //第二维[0,1]表示这个点是否安全 
        inline void dfs(int x,int fa)
        {
            int i;
            long long Min=inf;
            bool bo=0;
            for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
            {
                dfs(to[i],x);
                dp[x][0][0]+=dp[to[i]][0][1];
                if(dp[to[i]][0][1]>dp[to[i]][1][1]) bo=1;
                else Min=min(Min,dp[to[i]][1][1]-dp[to[i]][0][1]);
                dp[x][0][1]+=min(dp[to[i]][0][1],dp[to[i]][1][1]);
                dp[x][1][1]+=min(min(dp[to[i]][0][0],dp[to[i]][0][1]),dp[to[i]][1][1]);
            }
            if(!bo)dp[x][0][1]+=Min;
            dp[x][1][1]+=Cost[x];
            return;
        }
        inline void Solve()
        {
            dfs(1,0);
            Wl(min(dp[1][0][1],dp[1][1][1]));
            return;
        }
        inline void Init()
        {
            tot=0;
            memset(head,0,sizeof head);
            return;
        }
    }T;
    int main()
    {
    //    freopen("guard6.in","r",stdin);
    //    freopen("my.out","w",stdout);
        int i;
        R(n);
        T.Init();
        for(i=1;i<=n;i++)
        {
            int rt,k,x;
            R(rt); R(Cost[rt]); R(k);
            while(k--) {R(x); T.add(rt,x); T.add(x,rt);}
        }
        T.Solve();
        return 0;
    }
    /*
    input
    6
    1 30 3 2 3 4
    2 16 2 5 6
    3 5 0
    4 4 0
    5 11 0
    6 5 0
    output
    25
    
    input
    1
    1 2 0
    output
    2
    
    input
    9
    2 16 3 1 3 4
    1 8000 3 5 6 7
    3 6000 1 8
    4 8000 0
    5 1 1 9
    6 900 0
    7 100 0
    8 2 0
    9 20 0
    output
    1019
    */
    View Code
  • 相关阅读:
    2017年5月15号课堂笔记
    2017年5月12号课堂笔记
    2017年5月8号课堂笔记
    2017年5月5号课堂笔记
    2017年4月26号课堂笔记
    不忘初心,坚持走下去
    2017年4月24号课堂笔记
    2017年4月21号课堂笔记
    2017年4月19号课堂笔记
    autoit UIA获取Listview的信息
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10356326.html
Copyright © 2020-2023  润新知