• 并查集的一般操作 ②


    RT

    题目描述

    明天就是母亲节了,电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢?听说在某个网站上有卖云朵的,小朋友们决定一同前往去看看这种神奇的商品,这个店里有n朵云,云朵已经被老板编号为1,2,3,……,n,并且每朵云都有一个价值,但是商店的老板是个很奇怪的人,他会告诉你一些云朵要搭配起来买才卖,也就是说买一朵云则与这朵云有搭配的云都要买,电脑组的你觉得这礼物实在是太新奇了,但是你的钱是有限的,所以你肯定是想用现有的钱买到尽量多价值的云。

    输入格式:

     第1行n,m,w,表示n朵云,m个搭配和你现有的钱的数目

     第2行至n+1行,每行ci,di表示i朵云的价钱和价值

     第n+2至n+1+m ,每行ui,vi表示买ui就必须买vi,同理,如果买vi就必须买ui

     输出格式:

     一行,表示可以获得的最大价值

    输入输出样例

    输入:      输出:

    5 3 10          1
    3 10
    3 10
    3 10
    5 100
    10 1
    1 3
    3 2
    4 2

    Solution

    通过观察,发现是一道并查集和01背包的好 题;

    只要把链接的云并成一组,然后对这些组进行dp就行了;

    详见代码

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    int n,m,w;int val[100010],wt[100010];
    ///**并查集**///
    struct b
    {
        int par[100010];
        inline void  ih(){for(int i=1;i<=n;i++)par[i]=i;}
        int f(int x){return par[x]=(par[x]==x)?x:f(par[x]);}
        int u(int x,int y)
        {
    
            val[f(x)]+=val[f(y)];
            wt[f(x)]+=wt[f(y)];
            par[f(y)]=f(x);
        }
    }s;
    int a,b;
    int ans,dp[100010];
    int val1[100010];int wt1[100010];int main()
    {
        //freopen("in","r",stdin);
        scanf("%d%d%d",&n,&m,&w);
        for(int i=1;i<=n;++i)
        {
            scanf("%d%d",&wt[i],&val[i]);
        }
        s.ih();
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d",&a,&b);
            s.u(a,b);
        }
        int sum=1;
        for(int i=1;i<=n;++i)        /// 巧妙的操作
        {
            if(s.par[i]==i)
            {
                val1[sum]=val[s.f(i)];
                wt1[sum]=wt[s.f(i)];
                sum++;
            }
        }
    ///**01背包*////
        for(int i=1;i<=sum;++i)
        {
           for(int j=w;j>=wt1[i];--j)
            {
                dp[j]=max(dp[j],dp[j-wt1[i]]+val1[i]);
            }
        }
        printf("%d",dp[w]);
    }
    View Code

    21:07:43

  • 相关阅读:
    Java排序算法之堆排序
    servlet学习总结(一)——HttpServletRequest(转载)
    servlet学习总结(一)——初识Servlet
    Java排序算法之快速排序
    Java排序算法之直接选择排序
    第八课、泛型编程简介
    第六课、算法效率的度量
    第四课、程序灵魂的审判
    第三课、初识程序的灵魂------------------------狄泰软件学院
    用solidity语言开发代币智能合约
  • 原文地址:https://www.cnblogs.com/AidenPearce/p/8280535.html
Copyright © 2020-2023  润新知