Live2D

洛谷P1455 搭配购买

点击跳转了解题意


题解:起初看到这道题,我以为它是一道像金明的预算方案一样的树形背包dp,但仔细观察发现了它们的不同,这道题规定了买一件物品其它

有关系的物品必须都买,再仔细一想,有了这种关系,主件和附件不就成了同一件物品了嘛,所以我们用并查集维护一下关系,然后将有关系

的物品合并为一件物品再做01背包即可。

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define maxn 10005
 6 
 7 using namespace std;
 8 
 9 int f[maxn],c[maxn],w[maxn];
10 int n,vmax,m;
11 int dp[maxn];
12 
13 inline int find(int k)
14 {
15     if(f[k]==k) return f[k];
16     return f[k]=find(f[k]);
17 }
18 
19 int main()
20 {
21     scanf("%d%d%d",&n,&m,&vmax);
22     for(int i=1;i<=n;i++)
23         f[i]=i;
24     for(int i=1;i<=n;i++)
25         scanf("%d%d",&w[i],&c[i]);
26     for(int i=1;i<=m;i++)
27     {
28         int x,y;
29         scanf("%d%d",&x,&y);;
30         int f1=find(x);
31         int f2=find(y);
32         f[f1]=f2;
33     }
34     for(int i=1;i<=n;i++)
35     {
36         int f1=find(i);
37         if(f1!=i)
38         {
39             c[f1]+=c[i];
40             w[f1]+=w[i];
41             c[i]=w[i]=0;
42         }
43     }
44     for(int i=1;i<=n;i++)
45         for(int v=vmax;v>=w[i];v--)
46             dp[v]=max(dp[v],dp[v-w[i]]+c[i]);
47     printf("%d",dp[vmax]);
48     return 0;
49 } 
P1455

 

posted @ 2019-08-18 11:46  Hoyoak  阅读(156)  评论(0编辑  收藏  举报