现在的位置: 首页 > 综合 > 正文

UVALive 2038 Strategic game

2013年01月12日 ⁄ 综合 ⁄ 共 1122字 ⁄ 字号 评论关闭

题目大意:给你一棵树,n个节点,现在需要照亮所有的边,问你最少需要在节点上放几个士兵?

思路:最简单的树形DP了吧,设d[ i ][ j ] 把表示节点i,状态为j时的把以i为根节点的子树的边全部照亮的最小值,j==0表示i节点不放兵,1表示放兵,那么d[ i ][ 0 ] = SIGMA(d[ v ][ 1 ]),d[ i ][ 1 ] = SIGMA(min(d[ v ][ 0 ],d[ v ][ 1 ])),v为i的子节点。

就是输入有点坑,又要抠。。 = =

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN = 1555 ;

struct Edge
{
    int t,next;
} edge[MAXN<<1];

int tot,head[MAXN];

void add_edge(int s,int t)
{
    edge[tot].t=t;
    edge[tot].next = head[s];
    head[s] = tot++;
}

int d[MAXN][3];

void dfs(int u,int fa)
{
    d[u][0] = 0;
    d[u][1] = 1;
    for(int e = head[u];e!=-1;e = edge[e].next)
    {
        int v = edge[e].t;
        if(v == fa) continue;
        dfs(v,u);
        d[u][0] += d[v][1];
        d[u][1] += min(d[v][0],d[v][1]);
    }
}

char str[111];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        tot=0;
        memset(head,-1,sizeof(head));
        for(int i = 0;i<n;i++)
        {
            scanf("%s",str);
            int flag = 0;
            int s,m;
            for(int j=0;str[j]!='\0';)
            {
                if(str[j]>='0'&&str[j]<='9')
                {
                    int tmp = str[j]-'0';
                    j++;
                    while(str[j]>='0'&&str[j]<='9')
                    {
                        tmp = tmp*10 + str[j]-'0';
                        j++;
                    }
                    //printf("tmp = %d\n",tmp);
                    if(flag==0)
                    {
                        s = tmp;
                        flag ++;
                    }
                    else if(flag==1)
                    {
                        m = tmp;
                    }
                }
                else j++;
            }
            //printf("s = %d.m = %d\n",s,m);
            int a;
            for(int j = 0;j<m;j++)
            {
                scanf("%d",&a);
                add_edge(s,a);
                add_edge(a,s);
            }
        }
        dfs(0,-1);
        printf("%d\n",min(d[0][0],d[0][1]));
    }
    return 0;
}

抱歉!评论已关闭.