1. 程式人生 > >洛谷P2016戰略遊戲

洛谷P2016戰略遊戲

價值 iostream == show code from using urn 簡單

傳送門啦

戰略遊戲這個題和保安站崗很像,這個題更簡單,這個題求的是士兵人數,而保安站崗需要求最優價值。

定義狀態$ f[u][0/1] $ 表示 $ u $ 這個節點不放/放士兵

根據題意,如果當前節點不放置士兵,那麽它的子節點必須全部放置士兵,因為要滿足士兵可以看到所有的邊,所以
$ f[u][0]+=f[v][1] $ ,其中$ v $ 是 $ u $ 的子節點

如果當前節點放置士兵,它的子節點選不選已經不重要了(因為樹形dp自下而上更新,上面的節點不需要考慮),所以
$ f[u][1]+=min(f[v][0],f[v][1]) $

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1505;

inline int read(){
    char ch = getchar();
    int f = 1 , x = 0;
    while(ch > '9' || ch < '0'){if(ch == '-')f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
    return x * f;
}

int n,flag,k,x;
int head[maxn],tot;
int f[maxn][5];

struct Edge{
    int from,to,next;
}edge[maxn << 1];

void add(int u,int v){
    edge[++tot].from = u;
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot;
}

void dfs(int u,int fa) {
    f[u][1] = 1 , f[u][0] = 0;
    for(int i=head[u];i;i=edge[i].next) {
        int v = edge[i].to;
        if(v != fa) {
            dfs(v , u);
            f[u][0] += f[v][1];
            f[u][1] += min(f[v][1] , f[v][0]);
        }
    }
}

int main(){
    n = read();
    for(int i=0;i<=n-1;i++){
        flag = read(); k = read();
        if(k == 0)continue;
        for(int i=1;i<=k;i++){
            x = read();
            add(flag , x);  add(x , flag);
        }
    }
    dfs(0 , -1);
    printf("%d\n",min(f[0][1] , f[0][0]));
    return 0;
}

洛谷P2016戰略遊戲