洛谷P2016戰略遊戲
阿新 • • 發佈:2018-10-31
價值 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戰略遊戲