【题目描述】
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 }