0
点赞
收藏
分享

微信扫一扫

1252. 搭配购买(并查集,特殊依赖01背包)

纽二 2022-02-07 阅读 24
c++算法

 

 分析:可以看成是特殊的有依赖的背包问题,因为有依赖的背包对于子树是可选可不选,这里是必选全部选,反而变得更加简单了

所以我们可以把一堆搭配看成一个集合,然后运用并查集维护并查集的拓展域,做01背包问题

并查集拓展域

  • 价格域 v ==集合中所有价值和
  • 价值域 w ==集合中所有价格和
#include <iostream>
#include <algorithm>
using namespace std;
const int N=10010;
int v[N];   //云的集合,价格
int w[N];   //价值
int p[N];  
int dp[N];
int find(int x)
{
    if(x!=p[x])
        p[x]=find(p[x]);
    return p[x];
}
int main()
{
    int n,m,W;
    cin>>n>>m>>W;
    for(int i=1;i<=n;i++)
        cin>>v[i]>>w[i],p[i]=i;
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        x=find(x),y=find(y);
        if(x==y) continue;    //为了避免重复加减
        //维护拓展域
        v[x]+=v[y];w[x]+=w[y];
        p[y]=x;
    }
    for(int i=1;i<=n;i++)
        if(p[i]==i)
        {
            for(int j=W;j>=v[i];j--)
                dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
        }
    cout<<dp[W];
    return 0;
}
举报

相关推荐

0 条评论