码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 1292-Strategic game

时间:2015-05-20 09:54:00      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:给出一棵树,在某个选择某个结点可以覆盖和它相连的所有边,问最少选多少个结点所有边都被覆盖。


解题思路:首先将无根树转化为有根树,0为根。
用d[i][0]表示不选择结点i时覆盖以结点i为根的子树最少要多少个结点,用d[i][1]表示选择结点i时覆盖以结点i为根的子树最少要多少个结点。若结点i不选,为了和覆盖所有和结点i相连的结点,则每个儿子都必须选,若结点i选,则每个儿子选择较小的那个值。按DFS顺序递推。
状态转移方程:

d[i][0]=sum { d[u][1] }(u是i的儿子)
d[i][1]=sum { min { d[u][0],d[u][1] } }+1(u是i的儿子)

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

vector <int> node[1550];
int n, DP[1550][2], vis[1550];

void init() {
    for (int i = 0; i <= n; i++) {
        node[i].clear();
        DP[i][0] = DP[i][1] = 0;
        vis[i] = 0;
    }

    int x, y, num;
    for (int i = 0; i < n; i++) {
        scanf("%d:(%d)", &x, &num);
        for (int j = 0; j < num; j++) {
            scanf("%d", &y);
            node[x].push_back(y);
            node[y].push_back(x);
        }
    }
}

void DPS(int root) {
    vis[root] = 1;
    int num = node[root].size();
    for (int i = 0 ; i < num; i++) {
        int child = node[root][i];
        if (vis[child])
            continue;
        DPS(child);
        DP[root][0] += DP[child][1];
        DP[root][1] += min(DP[child][0], DP[child][1]);
    }
    DP[root][1]++;
}

int main() {
    while (scanf("%d", &n) != EOF) {
        init();
        DPS(0);
        printf("%d\n", min(DP[0][0], DP[0][1]));
    }
    return 0;
}

UVA 1292-Strategic game

标签:

原文地址:http://blog.csdn.net/kl28978113/article/details/45850801

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!