• 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();
    
        }
    }
  • 相关阅读:
    洛谷P2661: 信息传递(图的遍历)
    洛谷P1305: 新二叉树
    洛谷 P1030 :求先序排列
    POJ 3041:Asteroids(二分图最大匹配)
    洛谷P2774 :方格取数问题( 网络流24题 奇偶建图+最小割)
    hdu 3061:Battle(最大权闭合图)
    hdu 1532:Drainage Ditches(Dinic算法)
    洛谷P1345: [USACO5.4]奶牛的电信Telecowmunication(拆点+最小割)
    hihoCoder1121 : 二分图一•二分图判定
    (转载)javascript客户端生成MD5值的函数代码
  • 原文地址:https://www.cnblogs.com/Norlan/p/4778719.html
Copyright © 2020-2023  润新知