[LSGDOJ 1299]搭配买卖

题目描述

joe觉得云朵很美,决定去山上的商店买一些云朵。商店里有n多云,云朵被编号为1,2,……,n,并且每朵云都有一个价值。但商店老板跟他说,一些云朵要搭配来买才好,所以买一朵云则与这多云有搭配的云都要买。但是Joe 的钱有限,所以他希望买的价值越多越好。

输入

第一行n,m,w,表示n多云,m个搭配,Joe有w的钱

第二只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

提示

n<=10000,m<=5000,w<=10000

题解:

此题很水,但是我却看错了题目,想到了另一种题目类型决定把这种也说说.

先讲此题:

这题意是有关联的要买就都买,于是用并查集合并,然后背包.

接下来是另一种:

我以为是拓扑序,买完这个就不买他的下层.

也就是说1->2->3可以只买2.3不买1

于是想到dfs一边,把所有的购买方案都看作一个物品(3,23,123)然后再背包

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=10005;
 7 int gi(){
 8     int str=0;char ch=getchar();
 9     while(ch>'9' || ch<'0')ch=getchar();
10     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
11     return str;    
12 }
13 struct node{
14     int w,val;
15 }a[N];
16 int fa[N],F[N];
17 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
18 int w[N],v[N],tot=0;
19 int main()
20 {
21     //freopen("pp.in","r",stdin);
22     int n=gi(),m=gi(),k=gi(),x,y;
23     for(int i=1;i<=n;i++)a[i].w=gi(),a[i].val=gi(),fa[i]=i;
24     for(int i=1;i<=m;i++)
25     {
26         x=gi();y=gi();
27         a[find(x)].val+=a[find(y)].val;
28         a[find(x)].w+=a[find(y)].w;
29         fa[find(y)]=find(x);
30     }
31     for(int i=1;i<=n;i++)if(fa[i]==i){w[++tot]=a[i].w;v[tot]=a[i].val;}
32     for(int i=1;i<=tot;i++)
33     {
34         for(int j=k;j>=w[i];j--)
35         {
36             F[j]=max(F[j-w[i]]+v[i],F[j]);
37         }
38     }
39     printf("%d",F[k]);
40     return 0;
41 }
原文地址:https://www.cnblogs.com/Yuzao/p/6903259.html