题目描述
明天就是母亲节了,电脑组的小朋友们在忙碌的课业之余挖空心思想着该送什么礼物来表达自己的心意呢?听说在某个网站上有卖云朵的,小朋友们决定一同前往去看看这种神奇的商品,这个店里有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
思路
水题,这题就是把几个绑定在一起的云看成一个个体,然后进行01背包
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cmath>
#include<cctype>
#include<stack>
#include<map>
#include<string>
#include<cstdlib>
#include<sstream>
#define ll long long
#define ull unsigned long long
const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 10;
const int mod = 1e4+7;
int dp[maxn],mark[maxn],tc[maxn],td[maxn];
int main()
{
int n,m,w,c[maxn],d[maxn],u[maxn],v[maxn];
scanf("%d %d %d",&n,&m,&w);
for(int i=1;i<=n;i++) scanf("%d %d",&c[i],&d[i]);
for(int i=1;i<=m;i++) scanf("%d %d",&u[i],&v[i]);
int cnt=0;
for(int i=1;i<=m;i++)
{
if(mark[u[i]]==0&&mark[v[i]]==0)
{
cnt++;
mark[u[i]]=cnt;
mark[v[i]]=cnt;
tc[cnt]+=c[u[i]]+c[v[i]];
td[cnt]+=d[u[i]]+d[v[i]];
}
else if(mark[u[i]]==0&&mark[v[i]]!=0)
{
mark[u[i]]=mark[v[i]];
tc[mark[u[i]]]+=c[u[i]];
td[mark[u[i]]]+=d[u[i]];
}
else if(mark[u[i]]!=0&&mark[v[i]]==0)
{
mark[v[i]]=mark[u[i]];
tc[mark[v[i]]]+=c[v[i]];
td[mark[v[i]]]+=d[v[i]];
}
}
for(int i=1;i<=n;i++)
{
if(mark[i]==0)
{
cnt++;
tc[cnt]=c[i];
td[cnt]=d[i];
}
}
for(int i=1;i<=cnt;i++)
for(int j=w;j>=tc[i];j--)
dp[j]=std::max(dp[j],dp[j-tc[i]]+td[i]);
printf("%d\n",dp[w]);
return 0;
}