hdu 1054 Strategic Game

http://acm.hdu.edu.cn/showproblem.php?pid=1054

题意:在一个树中有一些结点,若在一个结点占一个士兵,则和这一节点相邻的结点被控制(包括此节点),求最少需要多少个士兵;

思路:用树形dp,num[i][2]数组存储这个结点存在和不存在士兵的情况下子节点所需士兵的最少数目;

code:

View Code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;
struct node
{
    int num;
    int next[1510];
    node()
    {
        num = 0;
        memset(next,0,sizeof(next));
    }
}link[1510];
int num[1510][2];
//int visit[1010];
int n = 0;
int a = 0;
int m = 0;
int temp = 0;
int nn[1510];
void dfs(int q)
{
    if(link[q].num == 0)
    {
       num[q][0] = 0;
       num[q][1] = 1;
       //printf("%d  hhh\n",q);
       return ;
    }
    for(int i = 0;i < link[q].num; ++i)
    {
        dfs(link[q].next[i]);
        //printf("%d  hhgjjfdk\n",link[q].next[i]);
        if(num[link[q].next[i]][1] > num[link[q].next[i]][0])
        num[q][1]+= num[link[q].next[i]][0];
        else
        num[q][1]+= num[link[q].next[i]][1];
        num[q][0]+= num[link[q].next[i]][1];
    }
    num[q][1]+=1;
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        memset(link,0,sizeof(link[0]));
        memset(num,0,sizeof(num));
        //memset(visit,0,sizeof(visit));
        memset(nn,0,sizeof(nn));
        for(int i = 1;i <= n; ++i)
        {
            scanf("%d:(%d)",&a,&m);
            for(int j = 0;j < m; ++j)
            {
                scanf("%d",&temp);
                link[a].next[j] = temp;
                nn[temp]++;
            }
            link[a].num = m;
        }
        int begin = 0;
        for(int j = 0; j < n; ++j)
        if(nn[j] == 0)
        {
            begin = j;
            break;
        }
        dfs(begin);
        int ans = 0;
        ans = min(num[begin][0],num[begin][1]);
        printf("%d\n",ans);
    }
}
posted @ 2012-04-23 20:55  LT-blogs  阅读(204)  评论(0编辑  收藏  举报