LA 2038 Strategic game

来源:互联网 发布:帝国cms绑定域名 编辑:程序博客网 时间:2024/06/02 03:31

题目描述 传送门


注意此题蓝书上的翻译有误!
蓝书上说“使得每个没有选中的节点至少和一个以选中的节点相邻”,而题目要求的是使得每条边至少和一个以选中的节点相邻。
搞得我硬是找不出错。
简单的树上DP,设d(i,0)d(i,1)分别为以i为根节点的子树i点不放兵和放兵总共所需的最小放兵数量,转移简单。


代码

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cctype>#include<vector>using namespace std;const int maxn=1505;const int INF=1e9;int d[maxn][3],n;vector<int> g[maxn];void read(int &x){    char c=' ';    while(!isdigit(c)) c=getchar();    x=0;    while(isdigit(c)) x=x*10+c-'0',c=getchar();}void dfs(int u,int fa){    d[u][1]=1;d[u][0]=0;    for(int i=0;i<g[u].size();i++) if(g[u][i]!=fa){        dfs(g[u][i],u);        d[u][1]+=min(d[g[u][i]][1],d[g[u][i]][0]);        d[u][0]+=d[g[u][i]][1];    }}int main(){    while(scanf("%d",&n)!=EOF){        for(int i=0;i<n;i++) g[i].clear();        for(int i=0;i<n;i++){            int a,m,b;            read(a);read(m);            for(int i=0;i<m;i++){                read(b);                g[a].push_back(b);                g[b].push_back(a);            }        }        dfs(0,0);        printf("%d\n",min(d[0][1],d[0][0]));    }    return 0;}