Problem Description
Joe觉得云朵很美,决定去山上的商店买一些云朵。商店里有n朵云,云朵被编号为1,2,...,n,并且每朵云都有一个价值。但是商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这朵云有搭配的云都要买。但是Joe的钱有限,所以他希望买的价值越多越好。
Input
输入有多组数据,每组数据第1行n(<=10000)、m(>=5000)、w(<=10000),表示n朵云,m个搭配,Joe有w的钱。
第2至n+1行,每行ci、di表示i朵云的价钱和价值。
第n+2至n+1+m行,每行ui、vi表示买ui就必须买vi,同理,如果买vi就必须买ui。
Output
对于每组数据,输出一行,表示可以获得的最大价值。
Sample Input
5 3 10
3 10
3 10
3 10
5 100
10 1
1 3
3 2
4 2
Sample Output
1
//关键字:并查集+01背包
//标程:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct item
{
int price, val;
}p[10010], a[10010];
int father[10010], dp[10010];
int findx(int x)
{
return father[x] == x ? x : father[x];
}
void _union(int u,int v)
{
u = findx(u);
v = findx(v);
father[u] = v;
a[v].price += a[u].price;
a[v].val += a[u].val;
}
int main()
{
// freopen("a.txt","r",stdin);
int n, m, w, i, j;
while(scanf("%d%d%d",&n,&m,&w)!=EOF)
{
for(i = 1; i <= n; ++ i)
scanf("%d%d",&p[i].price,&p[i].val);
for(i = 1; i <= n; ++ i)
{
father[i] = i;
a[i] = p[i];
}
int u, v;
for(i = 1; i <= m; ++ i)
{
scanf("%d%d",&u,&v);
_union(u,v);
}
memset(dp,0,sizeof(dp));
for(i = 1; i <= n; ++ i)
if(father[i] == i)
{
for(j = w; j >= a[i].price; j --)
dp[j] = max(dp[j],dp[j-a[i].price] + a[i].val);
}
printf("%d\n",dp[w]);
}
return 0;
}
搭配购买
最新推荐文章于 2023-06-02 13:51:49 发布