zoukankan      html  css  js  c++  java
  • HDU ACM 1054 Strategic Game 二分图最小顶点覆盖?树形DP

    分析:这里使用树形DP做。

    1、最小顶点覆盖做法:最小顶点覆盖 == 最大匹配(双向图)/2。

    2、树形DP:
    dp[i][0]表示i为根节点,而且该节点不放,所需的最少的点数。
    dp[i][1]表示i为根节点,而且该节点放,所须要的最少的点数。

    dp[i][0]=sum(dp[son[i][j]][1]) 该点不放。则它的儿子节点必须都放,仅仅有这样之间的边才干够被覆盖。
    dp[i][1]=sum(min(dp[son[i][j]][0],dp[son[i][j]][1])) 该点放的话,则它的儿子节点有两种决策。放或不放,取min就可以。

    #include<iostream>
    #include<vector>
    #include<limits.h>
    using namespace std;
    
    #define N 1505
    int dp[N][2];    //dp[i]表示以i为根节点时所须要的最小点数
    int f[N];        //用来记录父节点
    vector<int> son[N]; //记录儿子节点
    
    int min(int x,int y)
    {
    	return x<y?

    x:y; } int dfs(int pos,int v) { int sum,i; if(dp[pos][v]!=INT_MIN) return dp[pos][v]; sum=v; for(i=0;i<son[pos].size();i++) if(v==1) //当前节点选 sum+=min(dfs(son[pos][i],0),dfs(son[pos][i],1)); else sum+=dfs(son[pos][i],1);//当前节点不选,子节点必选 dp[pos][v]=sum; return sum; } int main() { int ans,n,i,x,m,j,t; while(scanf("%d",&n)==1) { for(i=0;i<n;i++) { son[i].clear(); f[i]=i; dp[i][0]=dp[i][1]=INT_MIN; } for(i=0;i<n;i++) { scanf("%d:(%d)",&x,&m); for(j=0;j<m;j++) { scanf("%d",&t); son[x].push_back(t); f[t]=x; } } for(i=0;i<n;i++) if(f[i]==i) //找到根节点 { ans=min(dfs(i,0),dfs(i,1)); break; } printf("%d ",ans); } return 0; }



  • 相关阅读:
    @support浏览器兼容判断 以及 @media媒体查询
    关于BFC的总结
    JS—二维数组的创建
    JS—操作符优先级
    JS—事件对象
    JS—事件
    DOM—addEventListener() & removeEventListener()
    高级算法——动态规划(斐波那契函数实例)
    对象字面量的使用
    小程序日历 IOS真机预览问题
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5105613.html
Copyright © 2011-2022 走看看