zoukankan      html  css  js  c++  java
  • 士兵守卫(同P2016 战略游戏) 树形DP

    题目描述】

    Bob特别喜欢战略游戏,但有时他不能尽快找到最优解,所以他就很伤心。现在他又有一个问题,他必须保卫一个中世纪的城市,这个城市的道路形成了一棵树。他需要在树的节点上放最少的士兵来观察所有的边。你能帮助他么?

    例如右图就只需要一个士兵放在1号节点。

    【输入格式】

    输入文件soldier.in中有多组数据,每组数据的第一行N表示点的个数。接下来N行每行格式如下

    x:(k) a1 a2 … ak(x为点的编号,k为与其相连的子节点个数,a1, a2, …, ak分别为子节点的编号)

    【输出】

    输出文件soldier.out,对于每组数据输出一行一个数,即最少士兵数。

    【输入样例】

     4

    0:(1) 1

    1:(2) 2 3

    2:(0)

    3:(0)

    5

    3:(3) 1 4 2

    1:(1) 0

    2:(0)

    0:(0)

    4:(0)

    【输出样例】

    1

    2

    【数据规模】

    0 < N<= 1500, 0 <= x < N


    一道听起来就会,但是不会写的树形DP,转移方程没什么改变,就是处理的时候注意些,小心点打。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define il inline
    using namespace std;
    il int gi()
    {
        int x=0,y=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
            {
                if(ch=='-')
                    y=-1;
                ch=getchar();
            }
        while(ch>='0'&&ch<='9')
            {
                x=x*10+ch-'0';
                ch=getchar();
            }
        return x*y;
    }
    int pre[100045],cnt;
    struct edge
    {
        int next,to;
    }e[100045];
    void add(int from,int to)
    {
        e[++cnt].next=pre[from];
        e[cnt].to=to;
        pre[from]=cnt;
    }
    int f[1545][2];
    void dfs(int x,int y)
    {
        f[x][1]=1;
        int r=pre[x];
        while(r!=-1)
            {
                if(e[r].to!=y)
                {
                    dfs(e[r].to,x);
                    f[x][0]+=f[e[r].to][1];
                    f[x][1]+=min(f[e[r].to][0],f[e[r].to][1]);
                }
                r=e[r].next;
            }
    }
    int num[1545];
    int main()
    {
        freopen("soldier.in","r",stdin);
        freopen("soldier.out","w",stdout);
        int n,x;
        while(cin>>n)
        {
            memset(f,0,sizeof(f));
            cnt=0;
            memset(pre,-1,sizeof(pre));
            for(int i=0;i<n;i++)
                {
                    x=gi();
                    num[x]=gi();
                    for(int j=1;j<=num[x];j++)
                        {
                            int y=gi();
                            add(y,x);
                            add(x,y);
                        }
                }
            dfs(0,-1);
            printf("%d
    ",min(f[0][0],f[0][1]));
        }
        return 0;
    }
    PEACE
  • 相关阅读:
    git stash回退
    基于git tag快速修复
    Go语言开发规范
    defer实现原理
    string数据结构
    关于const iota
    struct
    map数据结构底层详解
    go 函数进阶
    go 内存分配原理
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7455326.html
Copyright © 2011-2022 走看看