文章标题 HDU 1054 :Strategic game (树形DP)

来源:互联网 发布:sharpdesk软件下载 编辑:程序博客网 时间:2024/06/18 14:22

传送门
题意:有n个节点,n-1条条边的树,然后要我们选择最少的点,使得这些点能将所有的边看到。
分析:树形DP ,dp[i][2],用0表示i这个点不选择,1表示i这个点选择,然后当对于u这个节点,如果不选择,那么其儿子节点就必须都得选择,所以有dp[u][0]+=dp[v][1] (v表示u的所有的儿子节点)
当选择u这个节点时,dp[u][1]=min(dp[v][0],dp[v][1]),即所有其儿子节点中需要选择的点的最小值
代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <set>#include <map>#include <algorithm>#include <math.h>#include <vector>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=1e5+10;int dp[maxn][2];//0表示不放,1表示放vector<int>G[maxn];void dfs(int u,int fa){    dp[u][0]=0;    dp[u][1]=1;    for (int i=0;i<G[u].size();i++){        int v=G[u][i];        if (v==fa)continue;        dfs(v,u);        dp[u][0]+=dp[v][1];        dp[u][1]+=min(dp[v][0],dp[v][1]);    }} int n;int main(){    while (scanf ("%d",&n)!=EOF){        for (int i=0;i<=n;i++)G[i].clear();        int u,v,tmp;        for (int i=0;i<n;i++){            scanf ("%d:(%d)",&u,&tmp);            //printf ("%d %d\n",u,tmp);            while (tmp--){                scanf ("%d",&v);                G[u].push_back(v);                G[v].push_back(u);            }        }        dfs(0,-1);        int ans=min(dp[0][0],dp[0][1]);        printf ("%d\n",ans);    }    return 0;}
原创粉丝点击