zoukankan      html  css  js  c++  java
  • POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 1220 Party at Hali-Bula(树型动态规划)

    POJ 3342 Party at Hali-Bula / HDU 2412 Party at Hali-Bula / UVAlive 3794 Party at Hali-Bula / UVA 1220 Party at Hali-Bula(树型动态规划)

    Description

    Dear Contestant,

    I'm going to have a party at my villa at Hali-Bula to celebrate my retirement from BCM. I wish I could invite all my co-workers, but imagine how an employee can enjoy a party when he finds his boss among the guests! So, I decide not to invite both an employee and his/her boss. The organizational hierarchy at BCM is such that nobody has more than one boss, and there is one and only one employee with no boss at all (the Big Boss)! Can I ask you to please write a program to determine the maximum number of guests so that no employee is invited when his/her boss is invited too? I've attached the list of employees and the organizational hierarchy of BCM.

    Best,
    --Brian Bennett

    P.S. I would be very grateful if your program can indicate whether the list of people is uniquely determined if I choose to invite the maximum number of guests with that condition.

    Input

    The input consists of multiple test cases. Each test case is started with a line containing an integer n (1 ≤ n ≤ 200), the number of BCM employees. The next line contains the name of the Big Boss only. Each of the following n-1 lines contains the name of an employee together with the name of his/her boss. All names are strings of at least one and at most 100 letters and are separated by blanks. The last line of each test case contains a single 0.

    Output

    For each test case, write a single line containing a number indicating the maximum number of guests that can be invited according to the required condition, and a word Yes or No, depending on whether the list of guests is unique in that case.

    Sample Input

    6
    Jason
    Jack Jason
    Joe Jack
    Jill Jason
    John Jack
    Jim Jill
    2
    Ming
    Cho Ming
    0

    Sample Output

    4 Yes
    1 No

    Http

    POJ:https://vjudge.net/problem/POJ-3342
    HDU:https://vjudge.net/problem/HDU-2412
    UVAlive:https://vjudge.net/problem/UVALive-3794
    UVA:https://vjudge.net/problem/UVA-1220

    Source

    树形动态规划

    题目大意

    在一棵树上选取若干个点,使得没有任意两个点相邻且点权值和最大,并问最大的方案数是否唯一。

    解决思路

    这题和POJ2342其实是差不多的,只是增加了一个要判断是否唯一。那么关于本题的基本框架请到这里来看,本文着重讲一下如何判断唯一性。

    我们知道对于一个点i和其儿子节点j来说,F[i][0]=sum(max(F[j][1],F[j][0])) ,F[i][1]=sum(F[j][0])+Value[i](上题已经说过啦),那么我们只要再加一个bool数组来存放方案是否唯一就可以啦。

    我们定义Unique[i]为判断是否唯一的数组,0表示不唯一,1表示唯一;Unique[i][0]表示不选i时的唯一性,Unique[i][1]表示选i时的唯一性。

    首先来看Unique[i][1]。我们知道F[i][1]=sum(F[j][0]),也就是说i只要有任意一颗子树不唯一,i就不唯一,所以有if (Unique[j][0]==0) Unique[i][1]=0;

    再来看Unique[i][0]。因为F[i][0]=sum(max(F[j][0],F[j][1])),所以Unique[i][0]应该与F[j][0],F[j][1]中大的的Unique有关。

    最后要注意的是,F[j][0]是可能为0的,也就是说没有选节点(这在叶子结点的上一层节点会出现),这个时候对于Unique[j][0]的讨论是无意义的(没有点怎么会有不同的方案呢),所以要跳过(楼主在这里WA了好多次)。更多细节请参看代码

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    #include<string>
    #include<map>
    using namespace std;
    
    const int maxN=300;
    const int inf=2147483647;
    
    int n;
    int F[maxN][5];
    vector<int> E[maxN];
    bool Unique[maxN][5];
    map<string,int> Map;//因为输入的是字符串,所以我们用一个Map将其转换成数字编号
    
    void dfs(int u);
    
    int main()
    {
        while (cin>>n)
        {
            if (n==0)
                break;
            memset(F,0,sizeof(F));
            memset(Unique,0,sizeof(Unique));
            for (int i=1;i<=n;i++)
                E[i].clear();
            Map.clear();
            string u,v;
            int cnt=0;
    
            cin>>u;
            cnt++;
            Map[u]=cnt;
            int Boss=cnt;
    
            for (int i=1;i<n;i++)//输入字符串并分配编号
            {
                cin>>u>>v;
                if (Map[u]==0)
                    Map[u]=++cnt;
                if (Map[v]==0)
                    Map[v]=++cnt;
                E[Map[v]].push_back(Map[u]);
                //In[Map[u]]++;
            }
    
            dfs(Boss);
    
            bool ok;
            cout<<max(F[Boss][1],F[Boss][0])<<' ';
            if (F[Boss][1]==F[Boss][0])
                ok=0;
            else
                if (F[Boss][1]>F[Boss][0])
                    ok=Unique[Boss][1];
            else
                ok=Unique[Boss][0];
            if (ok)
            {
                cout<<"Yes"<<endl;
            }
            else
                cout<<"No"<<endl;
            /*for (int i=1;i<=n;i++)
                cout<<F[i][0]<<' '<<F[i][1]<<endl;
            cout<<endl;
            for (int i=1;i<=n;i++)
                cout<<Unique[i][0]<<' '<<Unique[i][1]<<endl;*/
        }
        return 0;
    }
    
    void dfs(int u)
    {
        Unique[u][1]=Unique[u][0]=1;//唯一性先置为唯一
        for (int i=0;i<E[u].size();i++)
        {
            int v=E[u][i];
            dfs(v);
    
            if ((Unique[v][0]==0)&&(F[v][0]!=0))//注意这里一定要有F[v][0]!=0这一句,因为若不加的话那些没有选择任何节点的方案也会统计进去,造成出错
                Unique[u][1]=0;
            F[u][1]+=F[v][0];
    
            //F[u][0]+=max(F[v][0],F[v][1]);
            if (F[v][0]>F[v][1])
            {
                F[u][0]+=F[v][0];
                if (Unique[v][0]==0)
                    Unique[u][0]=0;
            }
            else
                if (F[v][0]<F[v][1])
                {
                    F[u][0]+=F[v][1];
                    if (Unique[v][1]==0)
                        Unique[u][0]=0;
                }
            else if (F[v]!=0)//这里的F[v]!=0也必须有!否则会出现和上面一样的情况
            {
                F[u][0]+=F[v][0];
                Unique[u][0]=0;
            }
        }
        F[u][1]++;
        return;
    }
    
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    正则表达式匹配
    最长回文子串
    无重复字符的最长子串
    n个骰子的点数之和
    关于模型选择
    最小堆
    kmeans++
    Dijkstra 算法
    mapreduce中获取输入文件的路径
    mapreduce数据不平衡时的处理方法
  • 原文地址:https://www.cnblogs.com/SYCstudio/p/7138185.html
Copyright © 2011-2022 走看看