并查集的一般操作 ②

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]);
}

21:07:43

原文地址:https://www.cnblogs.com/AidenPearce/p/8280535.html

时间: 2024-08-02 16:35:56

并查集的一般操作 ②的相关文章

关于一般的并查集求根操作的一组对照研究

说道并查集,大家一定对于以多叉树状结构为基础的并查集并不陌生最常见的两种写法如下 1 private function getfat(x:longint):longint; 2 begin 3 while x<>c[x] do x:=c[x]; 4 exit(x); 5 end; 1 private function getfat(x:longint):longint; 2 begin 3 if x<>c[x] then exit(getfat(c[x])) else exit(x

HDU 2473 Junk-Mail Filter (并查集的删除操作)

Problem Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) Extract the common characteristics from the incoming email. 2) Use a filter matching the set of common characteristics extracted to determine w

并查集的删除操作

C - Junk-Mail Filter  HDU - 2473 题目大意:就是一堆信件,然后有两个操作,一个是把一堆信件归在一个文件夹,一个就是把一个信件从文件夹中取出,最后问有多少个文件夹,一开始所有信件都是单独的文件夹. 其实就是一个简单的并查集删除的操作,当删除时就创建新的结点来代替它,要注意的是数组的范围,虽然信件只有10的5次方,但是操作有10的6次方,因为删除时还得创建新节点,所以数组一定要开大,不然不是WR就是TL.最后的输出可以直接用set,也可以用数组标记信件是归在哪个文件夹

[HDOJ2473]Junk-Mail Filter(并查集,删除操作,马甲)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2473 给两个操作:M X Y:将X和Y看成一类. S X:将X单独划归成一类. 最后问的是有多少类. 并查集,但是带有删除操作.然而并查集本身不支持删除,网上说可以引入一个id来表示一个点.就好像一个人上网有很多小号一样,假如这个人的小号被封掉并且永久不能解封,还想继续玩下去的话那就重新建一个号,再生成一个id,表示这个id是这个人就好了. 注意在删除操作的时候不能把原来id的pre值重置. 1 /

zoj 3261 Connections in Galaxy War(并查集+离线逆向操作)

 题目:给出一些点,每个点有权值,然后有一些边,相连.无向的.然后有一些操作 query a.表示从a出发的能到达的所有点权值最大的点的编号(相同取编号最小,而且权值要比自己大) destory a,b 表示删除连接a,b的边 思路并查集,但是要逆向处理,所以先离线读入,从后向前处理,于是对于destroy操作,等价于连接两个点的操作,然后对于每个询问输出即可 #include<cstdio> #include<cstring> #include<cmath> #i

并查集的一般操作 ①

Rt 题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路.问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路) 输入输出格式 输入格式: 第1行两个正整数N,M 下面M行,每行3个正整数x, y, t,告诉你这条公路连着x,y两个村庄,在时间t时能修复完成这条公路.

并查集的一般操作 ④

RT 并查集一般操作最后一篇 原题 POJ1456 翻译: 给定N个商品,每个商品有利润Pi和过期时间di,每天只能卖一个商品,过期商品不能在卖,求如何安排每天买的商品,可以使收益最大.1≤N,pi,di≤10000. 发现,好像可以用贪心的想,从先要过期的商品中卖出利润大的: 就可以按时间排个序,然后依次按价格放入二叉堆中,每次用大的替换利润低的: 可以,不过这次想用另一种贪心策略. 我先卖利润大的商品,并且尽可能晚地卖出: 哦?...       interesting! 然后 我们就可以按

HLJU 1105 cpc 喵喵的拆分集合 (并查集的逆向操作)

1105: 喵喵的拆分集合 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 37  Solved: 8 [Submit][Status][Web Board] Description 众所周知,DoubleQ是DS(Data Structure)粉,她最爱DS了.现在她要实现一个神奇的DS,支持下列两个操作: -删除某条边,表示为"D x",即为删除第x条边 -查询两点是否属于一个集合,表示为"Q a b",即为查询节

朋友(并查集的删除操作 可看作是插入操作的逆序)

小 z 被选为他们村的村长, 现在小 z 调查他们村上的关系. 如果村民 a 和村民 b 是朋友, 村民 b 和村民 c 是朋友, 那么村民 a 和村民 c 也是朋友. 那么村上的村民就会形成一个"朋友" 团队, 现在小 z 想知道他们村长有多少个这样的团队. 同时, 他们村会有人离开村子到城里谋求发展, 那么小 z 也想知道, 当他们离开后村上的"朋友" 团队.★数据输入输入第一行包括两个整数, N, M. N 表示一共有 N 个人, M 表示一个共有M 对关系.