T1387:搭配购买(buy)

【题目描述】

Joe觉得云朵很美,决定去山上的商店买一些云朵。商店里有n朵云,云朵被编号为1,2,…...,n,并且每朵云都有一个价值。但是商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这朵云有搭配的云都要买。

但是Joe的钱有限,所以他希望买的价值越多越好。

【输入】

第1行n,m,w,表示n朵云,m个搭配,Joe有w的钱。

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

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

【输出】

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

【输入样例】

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

【输出样例】

1

 解题思路

  并查集 + 01背包;

  并查集 将搭配的云彩都整合起来;

  01背包进行获取最大价值;

代码如下

 1 #include<iostream>
 2 using namespace std;
 3 const int maxn = 10010;
 4 int n, m, k, f[maxn], dp[maxn], ci[maxn], di[maxn];
 5 struct node{
 6     int c, d;
 7 }t[maxn];
 8 void init(){
 9     for(int i = 1; i <= n; i++)        f[i] = i;
10 }
11 int getf(int v){
12     if(v == f[v])    return v;
13     else    return f[v] = getf(f[v]);
14 }
15 void meg(int v, int u){
16     int t1 = getf(v), t2 = getf(u);
17     if(t1 != t2)    f[t2] = t1;
18 }
19 int main(){
20     cin >> n >> m >> k;
21     init();
22     for(int i = 1; i <= n; i++)        cin >> ci[i] >> di[i];
23     for(int i = 1; i <= m; i++){
24         int x, y;
25         cin >> x >> y;
26         meg(x, y);
27     }
28     for(int i = 1; i <= n; i++)        getf(i);
29     for(int i = 1; i <= n; i++){
30         t[f[i]].c += ci[i];
31         t[f[i]].d += di[i];
32     }
33     for(int i = 1; i <= n; i++){
34         if(f[i] == i){
35             for(int j = k; j >= t[i].c; j--){
36                 dp[j] = max(dp[j], dp[j - t[i].c] + t[i].d);
37             }
38         }    
39     }
40     cout << dp[k] << endl;
41     return 0;
42 }
购买搭配

 

原文地址:https://www.cnblogs.com/zoom1109/p/11014344.html