題目描述
明天就是母親節了,電腦組的小朋友們在忙碌的課業之餘挖空心思想着該送什麼禮物來表達自己的心意呢?聽說在某個網站上有賣雲朵的,小朋友們決定一同前往去看看這種神奇的商品,這個店裏有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
3 10
3 10
3 10
5 100
10 1
1 3
3 2
4 2
輸出樣例
1
說明
30%的數據滿足:n<=100
50%的數據滿足:n<=1000;m<=100;w<=1000;
100%的數據滿足:n<=10000;0<=m<=5000;w<=10000.
神tm搭配,把搭配的物品合起來然後01揹包就好。
代碼如下
#include<iostream>
#include<cstdio>
using namespace std;
const int size = 20010;
int dp[size];
int f[size];
int w[size],v[size];
int wws[size];
int vs[size];
int find(int x)
{
if(f[x] == x)
return x;
return f[x] = find(f[x]);
}
int n,m,ww;
int main()
{
scanf("%d%d%d",&n,&m,&ww);
for(int i = 1 ; i <= n ; f[i] = i , i ++);
for(int i = 1 ; i <= n ; i ++)
scanf("%d%d",&w[i],&v[i]);
for(int i = 1 ; i <= m ; i ++)
{
int s,t;
scanf("%d%d",&s,&t);
int x = find(s);
int y = find(t);
if(x != y)
f[x] = y;
}
for(int i = 1 ; i <= n ; i ++)
{
wws[find(i)] += w[i];
vs[find(i)] += v[i];
}
for(int i = 1 ; i <= n ; i ++)
{
for(int j = ww ; j >= wws[i] ; j --)
{
dp[j] = max(dp[j],dp[j-wws[i]]+vs[i]);
}
}
cout<<dp[ww];
return 0;
}