zoukankan      html  css  js  c++  java
  • uva1220--树的最大独立集+判重

    题意是挑选尽量多的人,并且每个人都不和他的父节点同时出现,很明显的最大独立集问题,难点在于如何判断方案是否唯一。

    详情请见刘汝佳《算法竞赛入门经典--第二版》P282

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #define INF 1e6
    using namespace std;
    const int maxn = 205;
    
    char ch[105],fa[105];
    char trie[maxn][105];
    int k;
    int d[maxn][2],f[maxn][2];
    vector<int> g[maxn];
    
    int ID(char *s)//给每个字符串分配ID;
    {
        int i = 0;
        for(i = 0; i < k; ++i)
        {
            if(strcmp(s,trie[i]) == 0) {
                return i;
            }
        }
        if(i == k) strcpy(trie[k],s);
        k++;
        return k-1;
    }
    int dp(int u,int x)
    {
        if(d[u][x]!=-1) return d[u][x];//记忆化
        if(x == 1){
            int sum = 1;
            f[u][1] = 1;
            if(g[u].size() == 0) return d[u][1] = 1;
            for(int i = 0; i < g[u].size(); ++i)
            {
                sum+=dp(g[u][i],0);
                if(f[g[u][i]][0] == 0) {
                    f[u][1] = 0;
                }
            }
            return d[u][1] = sum;
        }
        else
        {
            int sum = 0;
            f[u][0] = 1;
            if(g[u].size() == 0) return d[u][0] = 0;
            for(int i = 0; i < g[u].size(); ++i)
            {
                int p = dp(g[u][i],0),q = dp(g[u][i],1);
                if(p == q)
                {
                    sum+=p;
                    f[u][0] = 0;
                }
                else if(p > q)
                {
                    sum+=p;
                    if(f[g[u][i]][0] == 0) f[u][0] = 0;
                }
                else if(p < q)
                {
                    sum+=q;
                    if(f[g[u][i]][1] == 0) f[u][1] = 0;
                }
            }
            return d[u][0] = sum;
        }
    }
    int main()
    {
        //freopen("in","r",stdin);
        int n;
        while(~scanf("%d",&n)&&n)
        {
            int from,to;
            k = 0;
            scanf("%s",ch);
            ID(ch);//big boss是0号
            for(int i = 1; i < n; ++i)
            {
                scanf("%s%s",ch,fa);
                from = ID(ch);
                to = ID(fa);
                g[to].push_back(from);
            }
            //printf("%d
    ",g[0].size());
            memset(d,-1,sizeof(d));
            dp(0,0);
            dp(0,1);
            if(d[0][0] > d[0][1])
            {
                printf("%d ",d[0][0]);
                if(f[0][0]) puts("Yes");
                else puts("No");
            }
            else if(d[0][0] < d[0][1])
            {
                printf("%d ",d[0][1]);
                if(f[0][1]) puts("Yes");
                else puts("No");
            }
            else
            {
                printf("%d ",d[0][1]);
                puts("No");
            }
            for(int i = 0; i < n; ++i) g[i].clear();
    
        }
    }
  • 相关阅读:
    linux系统数据落盘之细节
    不同类型文件“可读写”的含义
    zz存储系统中缓存的三种类型
    library满(磁带紊乱、虚拟机恢复失败)
    TSM日常维护
    入门级磁带机使用方法
    关于 tsm 磁带槽位
    TSM lan-free原理及配置
    TSM中备份(Backup)和归档(Archive)的区别
    指定stg备份 (即指定tape 磁带)
  • 原文地址:https://www.cnblogs.com/Norlan/p/4778719.html
Copyright © 2011-2022 走看看