• Party at Hali-Bula(树形DP+判断方案数是否唯一)


    Party at Hali-Bula

     UVA - 1220 

    题意: 
    公司里有n(n<=200)个人形成一个树状结构, 要求尽量选多的人,但不能同时选择一个人和他的直属上司,文最多能选多少人,以及是否方案唯一。 

      1 //dp[x][0]表示不选X节点能达到的最大人数,dp[x][1]表示选x节点的最大人数 
      2 //f数组含义和dp基本一致,f[x][0]表示如果不选x节点是否方案数唯一 f[x][1]表示如果选x节点方案数是否唯一
      3 //如果f数组为1表示方案数不唯一
      4 //对于一个根节点,如果其子节点中有一个方案数不唯一则其方案数不唯一
      5  
      6 #include<iostream>
      7 #include<cstdio>
      8 #include<cstring>
      9 #include<map>
     10 #include<vector>
     11 #include<algorithm>
     12 using namespace std;
     13 vector<int>v[500];
     14 string s1,s2;
     15 map<string,int>mp;
     16 int n;
     17 int flag;
     18 int dp[500][500];
     19 int f[500][500]; 
     20 int vis[500];
     21 void dfs(int x)
     22 {
     23     
     24     dp[x][0]=0;
     25     dp[x][1]=1;
     26     vis[x]=1;
     27     for(int i=0;i<v[x].size();i++)
     28     {
     29         int to=v[x][i];
     30         if(vis[to])
     31              continue;
     32         dfs(to);
     33         //选根节点 
     34         dp[x][1]+=dp[to][0];    
     35         if(f[to][0])
     36         {
     37             f[x][1]=1;
     38         }
     39         //不选根节点 
     40         if(dp[to][0]>dp[to][1])
     41         {
     42             dp[x][0]+=dp[to][0];
     43             if(f[to][0])
     44             {
     45                 f[x][0]=1;
     46             }
     47         }
     48         else
     49         {
     50             dp[x][0]+=dp[to][1];
     51             if(f[to][1]||dp[to][0]==dp[to][1])
     52             {
     53                 f[x][0]=1;
     54             }
     55         }
     56     }
     57     return ;
     58 }
     59 int main()
     60 {
     61     while(~scanf("%d",&n)&&n)
     62     {
     63         memset(vis,0,sizeof(vis));
     64         memset(dp,0,sizeof(dp));
     65         memset(f,0,sizeof(f));
     66         for(int i=0;i<500;i++)
     67             v[i].clear();
     68         mp.clear();
     69         cin>>s1;
     70         int cnt=1;
     71         if(!mp[s1])
     72         {
     73             mp[s1]=cnt++;
     74         }
     75         n--;
     76         while(n--)
     77         {
     78             cin>>s1>>s2;
     79             if(!mp[s1])
     80             {
     81                 mp[s1]=cnt++;
     82             }
     83             if(!mp[s2])
     84             {
     85                 mp[s2]=cnt++;
     86             }
     87             v[mp[s2]].push_back(mp[s1]);
     88         }
     89         flag=0;
     90         dfs(1);
     91         printf("%d ",max(dp[1][0],dp[1][1]));
     92         if(dp[1][0]==dp[1][1])
     93         {
     94             puts("No");
     95         }
     96         else
     97         {
     98              if(dp[1][0]>dp[1][1])
     99             {
    100                 if(f[1][0])
    101                     cout<<"No"<<endl;
    102                 else
    103                     cout<<"Yes"<<endl;
    104             }
    105             else if(dp[1][1]>dp[1][0])
    106             {
    107                 if(f[1][1])
    108                     cout<<"No"<<endl;
    109                 else
    110                     cout<<"Yes"<<endl;
    111             }
    112 
    113         }
    114     }
    115 }
  • 相关阅读:
    记录一下自己的洛谷的题解
    初学java 学生管理系统——v0002版本
    初学java 学生管理系统——v0001版本
    Redis守护进程作用+数据类型
    java实现发送短信验证码
    Kali入侵入门版笔记!!!
    2020实现ssh公网外联和外网远程穿透以及内网穿透防火墙
    监控键盘和鼠标记录内容和截屏,更新版本2.0,增加了Linux服务端!!!
    Git管理软件开发项目入门版
    2020年Windows下开机自动执行最强
  • 原文地址:https://www.cnblogs.com/1013star/p/9942412.html
Copyright © 2020-2023  润新知