Codeforces Round #383 (Div. 1) B

本文介绍了一种将并查集与01背包问题相结合的算法实现方法,通过并查集对物品进行分组,然后应用01背包算法求解最大价值问题。该方法的时间复杂度为O(nw),适用于解决具有特定分组约束条件的背包问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

就是01背包问题

先用并查集再用01背包

复杂度为nw

代码如下

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1005;
int dp[maxn],w[maxn],b[maxn],f[maxn];
vector<int>group[maxn]; 
int Find(int x)
{
	if(f[x]==x)
		return x;
	return f[x]=Find(f[x]);
 } 
void unite(int x,int y)
{
	int xx=Find(x);  
    int yy=Find(y);
    if(xx!=yy)  f[xx]=yy;
}
int main()
{
	int n,m,W;
	scanf("%d %d %d",&n,&m,&W);
	for(int i=1;i<=n;i++)
		scanf("%d",&w[i]);
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=0;i<m;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		unite(x,y);
	}
	for(int i=0;i<maxn;i++)
		group[i].clear();
	for(int i=1;i<=n;i++)
	    group[Find(i)].push_back(i);
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++)
	{
		if(Find(i)!=i)
			continue;
		for(int j=W;j>=0;j--){
			int sumw=0,sumb=0;
			for(int k=0;k<group[i].size();k++)
			{
				sumw+=w[group[i][k]];
				sumb+=b[group[i][k]];
				if(j>=w[group[i][k]]){
					dp[j]=max(dp[j],dp[j-w[group[i][k]]]+b[group[i][k]]);
				}
			}
			if(j>=sumw)
				dp[j]=max(dp[j],dp[j-sumw]+sumb);
		}
	}
	printf("%d\n",dp[W]);
	return 0;
 } 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值