题目描述
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 }