【題目描述】
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
【提示】
【數據範圍】
30%的數據保證:n≤100;
50%的數據保證:n≤1,000;m≤100;w≤1,000;
100%的數據保證:n≤10,000;0≤m≤5000;w≤10,000。
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define PII pair<int,int>
using namespace std;
const int N=1e4+5;
int n,m,w,fa[N],u,v,dp[N];
struct node
{
int x,y;
}a[N];
int Find(int x)
{
if(fa[x]!=x)
fa[x]=Find(fa[x]);
return fa[x];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> w;
for(int i=1;i<=n;i++)
{
fa[i]=i;
cin >> a[i].x >> a[i].y;
}
while(m--)
{
cin >> u >> v;
int x=Find(u),y=Find(v);
if(x!=y)
{
fa[x]=y;
a[y].x+=a[x].x;
a[y].y+=a[x].y;
}
}
for(int i=1;i<=n;i++)
{
if(i==fa[i])//或if(i==Find(i))
{
for(int j=w;j>=a[i].x;j--)
dp[j]=max(dp[j],dp[j-a[i].x]+a[i].y);
}
}
cout << dp[w] << endl;
return 0;
}