POJ - 1463 Strategic game 樹形DP

在這裏插入圖片描述

題目大意

給一棵樹, 在節點上放一個士兵, 可以把與節點相連的邊都監測到, 求把所有的邊都監測到所放的最少的士兵

樣例

Sample Input
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
Sample Output
1
2

思路
在這裏插入圖片描述
代碼

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

using namespace std;

const int  N = 1510;

int  ne[N], h[N], e[N], len;
int n;
bool vis[N];
int f[N][2];

void add(int a, int b)
{
    e[len] = b;
    ne[len] = h[a];
    h[a] = len++;
}

void dfs(int x)
{
    vis[x] = true;
    f[x][1] = 1;
    f[x][0] = 0;
    for(int i = h[x]; ~i; i = ne[i])
    {
        int y = e[i];
        if(vis[y]) continue;
        dfs(y);
        f[x][0] += f[y][1];
        f[x][1] += min(f[y][0], f[y][1]);
    }
}

int main()
{
    while(scanf("%d", &n) == 1)
    {
        memset(h, -1, sizeof h);
        memset(vis, false, sizeof vis);
        memset(f, 0, sizeof f);
        len = 0;
        for(int i = 0; i < n; i++)
        {
            int a, cnt;
            scanf("%d:(%d)", &a, &cnt);
            for(int j = 1; j <= cnt; j++)
            {
                int b;
                cin >> b;
                add(a, b);
                vis[b] = true;
            }
        }
        int root;
        for(int i = 0; i < n; i++)
            if(!vis[i])
            {
                root = i;
                break;
            }
         memset(vis, 0, sizeof vis);       
        dfs(root);
        cout << min(f[root][0], f[root][1]) << endl;
    }
    
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章