P1455 搭配购买
tags
01背包,并查集
思路
- 把在同一个集合中的背包合并成一个背包,(用并查集实现,路径压缩使得主背包为该集合的父亲)
- 合并背包的过程:
- 集合的合并
- 价格的合并
- 花费的合并
- 如何就用01背包解决了,合并后par[i]==i的才为背包
AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5,maxm=5e3+5;
int n,m,w;
int dp[10000000],a[maxn],b[maxn];
int par[maxn];
void init(){
for(int i=1;i<=n;i++)par[i]=i;
}
int find(int x){
return x==par[x]?x:par[x]=find(par[x]);
}
void unite(int x,int y){
x=find(x),y=find(y);
if(x==y)return;
a[x]+=a[y];
b[x]+=b[y];
par[y]=x;
}
struct wp{
int i,sum1,sum2;
};
int main(){
cin>>n>>m>>w;
for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
init();
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
unite(x,y);
}
for(int i=1;i<=n;i++){
if(par[i]==i){
for(int j=w;j>=a[i];j--){
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
}
}
cout<<dp[w]<<endl;
}