zoukankan      html  css  js  c++  java
  • 洛谷P1455 搭配购买

    题目描述

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

    输入输出格式

    输入

    第1行n,m,w,表示n朵云,m个搭配和你现有的钱的数目
    第2行至n+1行,每行(c_i),(d_i)表示i朵云的价钱和价值
    第n+2至n+1+m ,每行(u_i),(v_i)表示买(u_i)就必须买(v_i),同理,如果买(v_i)就必须买(u_i)

    输出

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

    思路

    用并查集将将搭配的云全部连到一个集合,再用一个01背包求值

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10000+5;
    int fa[maxn],c[maxn],w[maxn],f[maxn];
    int n,m,k,x,y;
    int find(int x){
    	if(x==fa[x])return x;
    	else return fa[x]=find(fa[x]);
    }//并查集代码
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&w[i],&c[i]);//输入
            fa[i]=i; 
        } 
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            if(find(x)!=find(y))
    		fa[find(y)]=find(x); //将两个集合合并
        }
        for(int i=1;i<=n;i++)
        	if(fa[i]!=i){//如果这个的不是这个集合的祖宗
            	c[find(i)]+=c[i];
            	w[find(i)]+=w[i]; 
            	c[i]=w[i]=0; //把价值和价钱都加到祖宗那去
        	}
        for(int i=1;i<=n;i++)
    		for(int j=k;j>=w[i];j--)
    			f[j]=max(f[j],f[j-w[i]]+c[i]); //典型的01背包
        printf("%d
    ",f[k]);//输出
        return 0;//结束
    }
    
  • 相关阅读:
    小小杨的影视空间
    关于励志的事情
    关于2020年的总结
    关于心情不好的时候
    关于我的2020年
    单链表基本操作的实现
    原型模式
    android—安卓系统文件目录结构
    android——apk安装文件的组成结构
    android——项目的组成结构
  • 原文地址:https://www.cnblogs.com/xzj213/p/10631584.html
Copyright © 2011-2022 走看看