1252. 搭配购买【并查集 + 01背包】

1252. 搭配购买【并查集 + 01背包】
https://www.acwing.com/problem/content/1254/
先处理并查集,将每一个连通块当成一个物品,这就转化成了01背包问题。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,w;
int p[N],price[N],s[N];//并查集
int V[N],W[N],f[N];//01背包
int find(int x)
{
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
unordered_map<int,int>mp;
int main(void)
{
    cin>>n>>m>>w;
    for(int i=1;i<=n;i++) p[i]=i;
    for(int i=1;i<=n;i++) cin>>price[i]>>s[i];
    for(int i=1;i<=m;i++)
    {
        int a,b; cin>>a>>b;
        if(find(a)!=find(b))
        {
            s[find(b)]+=s[find(a)];
            price[find(b)]+=price[find(a)];
            p[find(a)]=find(b);
        }
    }
    int cnt=1;
    for(int i=1;i<=n;i++) if(!mp[find(i)]) V[cnt]=price[find(i)],W[cnt++]=s[find(i)],mp[find(i)]++;
    for(int i=1;i<cnt;i++)
        for(int j=w;j>=V[i];j--)
            f[j]=max(f[j],f[j-V[i]]+W[i]);
    cout<<f[w];
    return 0;
}
上一篇:MySql基础 --- DML操作表


下一篇:循环渲染指令