搭配购买

来源:互联网 发布:大唐网络电视安卓版 编辑:程序博客网 时间:2024/05/15 21:59
Problem DescriptionJoe觉得云朵很美,决定去山上的商店买一些云朵。商店里有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 Input5 3 103 103 103 105 10010 11 33 24 2Sample Output1//关键字:并查集+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;}

0 0