首页 > 代码库 > SPOJ PT07X Vertex Cover

SPOJ PT07X Vertex Cover

题目意思: 一棵树,找到最少的点能覆盖到所有的边,(也就是每条边俩端 至少有一个在你找到的集合);

  解法:每条边只能被俩个点中的一个,或全部覆盖所以我们有树形DP来解:

DP[num][flag]//代表在子树NUM全部被覆盖的情况下,flag=1,这个店也被覆盖:flag=false  这个店没被覆盖;

  那么有了这样的想法大妈就很好写了毕竟树形DP  主要的初始化和合并的状态:

#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <cstdlib>using namespace std;const int maxn=100003;int n;int dp[maxn][2];struct Edge{    int to,pre;    Edge (int to=0,int pre=0):to(to),pre(pre){}};Edge edge[maxn*2];int head[maxn],pos;inline void add_edge(int s,int to){    edge[pos]=Edge(to,head[s]);    head[s]=pos++;}inline void inint(){    memset(head,-1,sizeof(head));    pos=0;}void dfs(int pa,int s){    dp[s][0]=0;    dp[s][1]=1;    for(int w=head[s];~w;w=edge[w].pre)    {        Edge &tmp=edge[w];        if(tmp.to==pa)continue;        dfs(s,tmp.to);        dp[s][0]+=dp[tmp.to][1];        dp[s][1]+=min(dp[tmp.to][0],dp[tmp.to][1]);    }}int main(){    int a,b;    while(~scanf("%d",&n))    {        inint();        memset(dp,0,sizeof(dp));        for(int i=2;i<=n;i++)        {            scanf("%d%d",&a,&b);            add_edge(a,b);            add_edge(b,a);        }        dfs(-1,1);        printf("%d\n",min(dp[1][0],dp[1][1]));    }    return 0;}