题目
01背包
分析
用并查集的方法,把需要一起买的处理,再用01背包。
状态转移方程:
f
[
j
]
=
max
(
f
[
j
]
,
f
[
j
−
w
[
i
]
+
c
[
i
]
)
f[j]=\max(f[j],f[j-w[i]+c[i])
f[j]=max(f[j],f[j−w[i]+c[i])
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
unsigned short n,t,m,fa[10001]; int f[10001];
unsigned short w[10001],c[10001];
int in(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int getf(int u){return (fa[u]==u)?u:fa[u]=getf(fa[u]);}
int main(){
n=in(); t=in(); m=in();
for (int i=1;i<=n;i++) w[i]=in(),c[i]=in(),fa[i]=i;
while (t--){
int x=in(),y=in();
int k1=getf(x),k2=getf(y);
if (k1!=k2) fa[k2]=k1,w[k1]+=w[k2],c[k1]+=c[k2];//并查集
}
for (int i=1;i<=n;i++)
if (fa[i]==i)
for (int j=m;j>=w[i];j--)
f[j]=max(f[j],f[j-w[i]]+c[i]);//01背包
printf("%d",f[m]);
return 0;
}