zoukankan      html  css  js  c++  java
  • UVA

    有 n 个员工,n-1个从属关系。

    不能同时选择某个员工和他的直接上司,问最多可以选多少人,以及选法是否唯一。

    树上的最大独立集问题。只不过多了一个判断唯一性。

    dp[u][0]表示不选这个点的状态,dp[u][1]表示选这个点的状态。

    如果不选 u, 那么 u点状态是由 dp[v][0] 或者 dp[v][1],大的那个点转移过来,唯一性同时也转移。

    如果选 u , 那么 u点状态是由所有的 dp[v][0] 转移过来,所以只有所有的 dp[v][0]状态的都唯一时,dp[u][1]才唯一。

    另外,我一直 WA 的原因在于给员工编号的时候没有判断有没有出现过,默认每行的第一个都是没有出现过的。瞎改了好久。

    吸取教训。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 100010
    
    vector<int> son[maxn], fa[maxn];
    int same[maxn], dp[maxn][2], f[maxn][2];
    
    
    void DP(int k)
    {
            dp[k][0] = 0, dp[k][1] = 1;
    
            f[k][1] = 1, f[k][0] = 1;
            for (int i = 0; i < son[k].size(); i++)
            {
                    int v = son[k][i];
                    DP(v);
    
                    dp[k][0] += max(dp[v][1], dp[v][0]);
    
                    if (dp[v][1] == dp[v][0]) f[k][0] = 0;
                    if (dp[v][1] > dp[v][0] && f[v][1] == 0) f[k][0] = 0;
                    if (dp[v][1] < dp[v][0] && f[v][0] == 0) f[k][0] = 0;
    
                    dp[k][1] += dp[v][0];
                    if (f[v][0] == 0) f[k][1] = 0;
            }
    }
    
    void init(int n)
    {
            for (int i = 0; i < n; i++)
                    son[i].clear();
            memset(f, 0, sizeof(0));
    }
    
    int main()
    {
            int n;
            while(~scanf("%d", &n) && n)
            {
                    init(n);
                    map<string, int> idx;
                    string s;
                    cin >> s;
                    idx[s] = 0;
                    int id = 0;
    
                    for (int i = 1; i <= n-1; i++)
                    {
                            string x, y;
                            cin >> x >> y;
                            if (!idx.count(x))
                                idx[x] = ++id;
                            if (!idx.count(y))
                                idx[y] = ++id;
                            son[idx[y]].push_back(idx[x]);
                    }
    
                    DP(0);
    
                    int uniq = 1;
                    if (dp[0][0] > dp[0][1] && f[0][0] == 0) uniq = 0;
                            else if (dp[0][0] < dp[0][1] && f[0][1] == 0) uniq = 0;
                            else if (dp[0][0] == dp[0][1]) uniq = 0;
    
                    printf("%d %s
    ", max(dp[0][0], dp[0][1]), uniq ? "Yes":"No");
            }
    }
  • 相关阅读:
    Unity3D-ScrollRect 各参数的代码引用以及作用
    Unity3D-坐标转换笔记
    angularJS中XHR与promise
    angularJS中的事件
    angularJS中如何写服务
    angularJS中如何写自定义指令
    angularJS内置指令一览
    angularJS中如何写控制器
    理解angularJS中作用域$scope
    如何写angularJS模块
  • 原文地址:https://www.cnblogs.com/ruthank/p/9485560.html
Copyright © 2011-2022 走看看