zoukankan      html  css  js  c++  java
  • 洛谷P2016 战略游戏

    题目描述:

    Bob喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。

    他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。

    注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。

    请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵.

    题解:

    一看就是树形DP题。

    我们设f(x) 表示选定 x, 保证子树合法,子树内所需要的最小点数。g(x) 表示不选择 x, 保证子树合法所需要的最小点数

    可以推出:

    f(x) = ∑min{f(son[x]), g(son[x])}

    g(x) = ∑f(son[x])

    附上代码:

    #include<cstdio>
    #define inf 1000000000
    int n,a,b,c,idx,head[1501],f[1501][2];
    struct Edge
    {
        int to,next;
    }edge[3001];
    int min(int x,int y)
    {
        if(x<y)
            return x;
        return y;
    }
    void addedge(int x,int y)
    {
        ++idx;
        edge[idx].to=y;
        edge[idx].next=head[x];
        head[x]=idx;
    }
    void dfs(int x,int from)
    {
        f[x][1]=1;
        f[x][0]=0;
        if(head[x]==0) f[x][0]=inf;
        for(int i=head[x];i;i=edge[i].next)
        {
            if(edge[i].to!=from)
            {
                dfs(edge[i].to,x);
                f[x][1]+=min(f[edge[i].to][1],f[edge[i].to][0]);
                f[x][0]+=f[edge[i].to][1];
            }
        }   
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);a++;
            for(int j=1;j<=b;j++)
            {
                scanf("%d",&c);c++;
                addedge(a,c);
                addedge(c,a);
            }
        }
        dfs(1,0);
        printf("%d",min(f[1][1],f[1][0]));
    } 
  • 相关阅读:
    Jenkins job 之间实现带参数触发
    svn hooks post-commit钩子自动部署
    Ubuntu PPA软件源
    图片文字OCR识别-tesseract-ocr
    scala 学习笔记十 元组
    scala 学习笔记九 定义操作符
    scala 学习笔记八 简洁性
    scala 学习笔记七 基于类型的模式匹配
    scala 学习笔记六 推导
    scala 学习笔记五 foreach, map, reduce
  • 原文地址:https://www.cnblogs.com/jiangminghong/p/9810312.html
Copyright © 2011-2022 走看看