zoukankan      html  css  js  c++  java
  • (树形DP)Strategic game POJ

    题意:

    给你一棵树,树的每一个节点可以守护与其相连的所有边,问你最少用多少个节点可以守护这整棵树

    思路:

    仔细思考不难发现,要想守护一条边,边的两个端点必须有一个可以被选(两个都选也可以),然后这个问题就变成了翻版的没有上司的舞会

    定义:dp[i][0]表示不选i,守护其子树需要多少点

        dp[i][0]表示选上i,守护其子树需要多少点

    状态转移方程:

        dp[i][0] =  ∑dp[j][1]  (i为j的父亲节点)  

         dp[i][1] = 1+∑min(dp[j][1],dp[j][0])  (i为j的父亲节点)

    vetcor忘记清空T了好几次。。。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
     using namespace std;
     const int maxn=1502;
     int dp[maxn][2],n,fa[maxn];//dp[i][0]代表不选i,dp[i][1]代表选i 
     vector<int> edge[maxn];
     void dfs(int x,int fa)
     {
         dp[x][0]=0,dp[x][1]=1;
        for(int i=0;i<edge[x].size();i++){
            if(edge[x][i]!=fa){
                dfs(edge[x][i],x);
                dp[x][0]+=dp[edge[x][i]][1];
                dp[x][1]+=min(dp[edge[x][i]][0],dp[edge[x][i]][1]);
            }
        } 
     }
     int main()
     {
         while(scanf("%d",&n)!=EOF){
             int x,num,y;
             for(int i=0;i<n;i++)
                 edge[i].clear();
             for(int i=0;i<n;i++){
                     num=0;
                 scanf("%d:(%d)",&x,&num);
                for(int j=1;j<=num;j++){
                    scanf("%d",&y);
                    edge[x].push_back(y);
                    edge[y].push_back(x);
                }
             }
             dfs(0,-1);
             printf("%d
    ",min(dp[0][0],dp[0][1]));
         }
      } 
  • 相关阅读:
    [转]tesseract api C++使用例子
    Flyway记录
    线程安全性和共享
    并发初解
    生产环境中遇到过什么问题?或者有没有自己解决什么问题比较自豪的
    Java白皮书关键词理解【随记】
    技术面试记录
    Mac下完全卸载IntelliJIdea
    docker提交镜像后运行新容器mysql无法启动
    IntelliJ IDEA切换SDK解决卡顿的问题
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12172495.html
Copyright © 2011-2022 走看看