zoukankan      html  css  js  c++  java
  • POJ 1463 Strategic game(树形DP)

    题意:给一棵树,当在某个结点上放置士兵时,与该点相邻的边就被看守住了,求最少需多少士兵才能看住树中所有边。

    分析:先将无根树有根化,然后DP。

    状态设计:

          1、dp[i][0],表示在结点 i 没放置士兵的情况下,看住以结点 i 为根的子树的所有边所需的最少士兵;

          2、dp[i][1],表示在结点 i 放置士兵的情况下,看住以结点 i 为根的子树的所有边所需的最少士兵。

    状态转移:

          1、dp[i][0]=∑dp[j][1],j 是 i 的儿子结点;(根结点不放士兵时,与其相连的边必须由儿子结点来看守)

          2、dp[i][1]=1+∑ ( MIN ( dp[j][0] , dp[j][1] ) ),j 是 i 的儿子结点。 (根结点放士兵时,儿子结点可放可不放)

    初始化:  d[i][0]=0,d[i][1]=1,其中 i 是叶子结点

    View Code
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    using namespace std;
    
    #define N 1510
    #define MAX(a,b) ((a)>(b)?(a):(b))
    #define MIN(a,b) ((a)<(b)?(a):(b))
    
    int n,p[N],d[N],maxd;
    vector<int>g[N];
    vector<int>rd[N];
    int dp[N][2];
    
    void init()
    {
        int i;
        maxd=0;
        for(i=0; i<n; i++)
        {
            g[i].clear();
            rd[i].clear();
        }
        memset(dp,0,sizeof(dp));
    }
    void read()
    {
        int i,j,k,cnt;
        for(k=0; k<n; k++)
        {
            scanf("%d:(%d)",&i,&cnt);
            while(cnt--)
            {
                scanf("%d",&j);
                g[i].push_back(j);
                g[j].push_back(i);
            }
        }
    }
    void dfs(int u,int fa)
    {
        int i,v;
        d[u]=(fa==-1)?0:d[fa]+1;
        rd[d[u]].push_back(u);
        maxd=MAX(maxd,d[u]);
        for(i=0; i<g[u].size(); i++)
        {
            v=g[u][i];
            if(v^fa)    dfs(v,p[v]=u);
        }
    }
    void DP()
    {
        int i,j,u;
        for(i=maxd; i>=0; i--)
        {
            for(j=0; j<rd[i].size(); j++)
            {
                u=rd[i][j];
                dp[u][1]+=1;
                if(i)
                {
                    dp[p[u]][0]+=dp[u][1];
                    dp[p[u]][1]+=MIN(dp[u][0],dp[u][1]);
                }
            }
        }
        printf("%d\n",MIN(dp[0][0],dp[0][1]));
    }
    int main()
    {
        int i,j,k;
        while(~scanf("%d",&n))
        {
            init();
            read();
            dfs(0,-1);
            DP();
        }
        return 0;
    }
  • 相关阅读:
    Android开发之Path类使用详解,自绘各种各样的图形!
    json数值和结构
    ajax异步请求不能刷新数据的问题
    关于javaBean中boolean类型变量的set和get注入后传到前端JS中的问题
    Js中的window.parent ,window.top,window.self详解
    db2中修改表字段的长度,查看表字段长度,以及查看表字段已存放值大小
    db2数据库中查找数据库表
    分页查询SQL
    ibatis动态语句加and 和不加and
    win7计划任务执行BAT文件问题
  • 原文地址:https://www.cnblogs.com/algorithms/p/2629183.html
Copyright © 2011-2022 走看看