• hdu 1054 最小点集覆盖 || 树形dp


     题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054

    树形dp专辑:http://blog.csdn.net/xymscau/article/details/7561605

    dp: 对于每个节点都设两个状态,取 或者 不取 

       如果父节点 不取,则所有儿子节点都得取, 如果父节点要取,则儿子节点可以取、可以不取。

      

      t为父节点,k为儿子节点:

       dp[t][0]+=dp[k][1];
       dp[t][1]+=min(dp[k][1],dp[k][0]);
      
      
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<vector>
     5 using namespace std;
     6 
     7 vector < int > Q[1505];
     8 int n, a,b,m,dp[1505][2],flag[1505],Min;
     9 
    10 void dfs(int t)
    11 {
    12     flag[t]=1;
    13     int s=( int )Q[t].size();
    14     if(s==0)
    15     {
    16         dp[t][1]=1;
    17         dp[t][0]=0;
    18         return ;
    19    //     cout << "^^^^   "<<t <<" "<<dp[t][1] << " "<<dp[t][0] <<endl;
    20     }
    21     dp[t][1]=1;
    22     for(int i=0;i<s;i++)
    23     {
    24         int k=Q[t][i];
    25         if(flag[k])  continue;
    26         dfs(k);
    27         dp[t][0]+=dp[k][1];
    28         dp[t][1]+=min(dp[k][1],dp[k][0]);
    29         // cout << t <<" "<<dp[t][1] <<"  "<<dp[t][0] <<endl;
    30     }
    31   //  cout <<"<<   "<< t <<" "<<dp[t][1] <<"  "<<dp[t][0] <<endl;
    32 }
    33 
    34 int main( )
    35 {
    36     while(~scanf("%d",&n)){
    37 
    38         Min=0;
    39         for(int i=0;i<n;i++)
    40             Q[i].clear();
    41         memset(flag,0,sizeof(flag));
    42         memset(dp,0,sizeof(dp));
    43         for(int i=0;i<n;i++)
    44         {
    45             scanf("%d:(%d)",&a,&m);
    46             for(int j=1;j<=m;j++)
    47             {
    48                 scanf("%d",&b);
    49                 Q[a].push_back(b);
    50                 Q[b].push_back(a);
    51             }
    52         }
    53 
    54         for(int i=0;i<n;i++)
    55         {
    56             if((int)Q[i].size()!=0)
    57             {
    58                 dfs(i);
    59                 Min=min(dp[i][1],dp[i][0]);
    60                 break;
    61             }
    62         }
    63 //                for(int i=0;i<=1;i++)
    64 //        {            for(int j=0;j<n;j++)
    65 //            printf("%d ",dp[j][i]);
    66 //            printf("
    ");
    67 //        }
    68 
    69         printf("%d
    ",Min);
    70     }
    71     return 0;
    72 }
    View Code
    
    

     最小点集覆盖 = 最大匹配数 

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<vector>
     5 using namespace std;
     6 
     7 vector < int > Q[1505];
     8 int n, a,b,m,sum,A[1505],B[1505];
     9 
    10 bool getnum( int i)
    11 {
    12     for(int j=0;j<(int)Q[i].size();j++)
    13     {
    14         int k=Q[i][j];
    15         if( A[k] ) continue;
    16         A[k]=1;
    17         if( B[k]==-1 || getnum( B[k] ) )
    18         {
    19             B[k]=i;
    20             return true;
    21         }
    22     }
    23     return false;
    24 }
    25 
    26 int main( )
    27 {
    28     while(~scanf("%d",&n)){
    29         sum=0;
    30         for(int i=0;i<n;i++)
    31             Q[i].clear();
    32         for(int i=0;i<n;i++)
    33         {
    34             scanf("%d:(%d)",&a,&m);
    35             for(int j=1;j<=m;j++)
    36             {
    37                 scanf("%d",&b);
    38                 Q[a].push_back(b);
    39                 Q[b].push_back(a);
    40             }
    41         }
    42         memset(B,-1,sizeof(B));
    43         for(int i=0;i<n;i++)
    44         {
    45             memset(A,0,sizeof(A));
    46             if( getnum(i) ){
    47                 //printf("& i= %d 
    ",i);
    48                 sum++;
    49             }
    50 //            for(int i=0;i<n;i++)
    51 //            printf("*%d ",B[i]);
    52 //            cout<<endl;
    53 
    54         }
    55         printf("%d
    ",sum/2);
    56     }
    57     return 0;
    58 }
    View Code
     
  • 相关阅读:
    VIM 编辑器命令
    Ubuntu LAMP 便捷配置
    Linux基础命令
    Sql sever 定时任务设置
    C#自动发送邮件
    序列化与反序列化
    字符串.特殊引用类型
    抽象方法、接口
    函数的返回值
    线程
  • 原文地址:https://www.cnblogs.com/lysr--tlp/p/two.html
Copyright © 2020-2023  润新知