0
点赞
收藏
分享

微信扫一扫

Arpa's weak amphitheater and Mehrdad's valuable Hoses CodeForces - 742D


并查集确定各组妹子 每组只选一人或全选 假设某组有k人 则有(k+1)个选择 构成分组背包

重点在于理解分组背包

 

其实就是搞个假背包 对于某个分组 其中每个人都有真背包转移而来 暂存到假背包中 最后把真假背包合并一下即可

 

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
const int maxn=1e3+10;

vector <int> pre[maxn];
int f[maxn],w[maxn],v[maxn],dp[maxn],tmp[maxn];
int n,m,s;

int getf(int p)
{
if(f[p]==p){
return p;
}
else{
return f[p]=getf(f[p]);
}
}

void unite(int u,int v)
{
int fu,fv;
fu=getf(u),fv=getf(v);
if(fu!=fv){
f[fv]=fu;
}
}

int main()
{
int i,j,k,x,y,sumw,sumv,ans;
scanf("%d%d%d",&n,&m,&s);
for(i=1;i<=n;i++){
scanf("%d",&w[i]);
}
for(i=1;i<=n;i++){
scanf("%d",&v[i]);
}
for(i=1;i<=n;i++){
f[i]=i;
}
while(m--){
scanf("%d%d",&x,&y);
unite(x,y);
}
for(i=1;i<=n;i++){
pre[getf(i)].pb(i);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
if(f[i]==i){
memset(tmp,0,sizeof(tmp));
sumw=0,sumv=0;
for(j=0;j<pre[i].size();j++){
sumw+=w[pre[i][j]],sumv+=v[pre[i][j]];
for(k=w[pre[i][j]];k<=s;k++){
tmp[k]=max(tmp[k],dp[k-w[pre[i][j]]]+v[pre[i][j]]);
}
}
for(k=sumw;k<=s;k++){
tmp[k]=max(tmp[k],dp[k-sumw]+sumv);
}
for(k=0;k<=s;k++){
dp[k]=max(dp[k],tmp[k]);
}
}
}
ans=0;
for(i=0;i<=s;i++){
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
return 0;
}

 

 

 


举报

相关推荐

0 条评论