【dp每一天】POJ - 1463 Strategic game (樹形dp)

POJ - 1463

題意: 全部邊覆蓋,所加的士兵的最小值,遞推式可直接看代碼。說起來邊覆蓋感覺好像。。二分圖?

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

using namespace std;
const int maxn = 1600;
struct node
{
    int to,next;
    node(){}
    node(int a,int b){to = a; next = b;}
}edge[maxn];
int h[maxn], in[maxn], out[maxn], dp[maxn][2];
int edgenum;
void init()
{
    edgenum = 0;
    for(int i = 0; i < maxn; i++)
        h[i] = -1, in[i] = out[i] = dp[i][0] = dp[i][1] = 0;
}
void add(int f,int t)
{
    edge[edgenum] = node(t,h[f]);
    h[f] = edgenum++;
}
int solve(int u)
{
    if(out[u] == 0)
    {
        dp[u][1] = 1;
        return 0;
    }
    int ret = 0,ret1 = 0;
    for(int i = h[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].to;
        solve(v);
        ret += dp[v][1];
        ret1 += min(dp[v][0],dp[v][1]);
    }
    dp[u][1] = ret1 + 1;
    dp[u][0] = ret;
    return 0;
}
int main()
{
    int n,a,b,c;
    while(~scanf("%d",&n))
    {
        init();
        for(int i = 0; i < n ; i++)
        {
            scanf("%d:(%d)",&a,&b);
            for(int j = 0; j < b; j++)
            {
                scanf("%d",&c);
                add(a,c);
                out[a] ++; in[c] ++;
            }
        }
        int root = -1;
        for(int i = 0; i < n; i++)
        {
            if(out[i] != 0 && in[i] == 0)
                root = i;
        }
        solve(root);
        printf("%d\n",min(dp[root][1],dp[root][0]));
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章