算法提高之搭配购买
-
核心思想:并查集 + 01背包
- 用并查集将每个连通块求出 并同时求出价值和体积
- 然后对根节点做01背包
-
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 10010; int n,m,vol; int v[N],w[N]; int p[N],f[N]; int find(int x) // 并查集 { if (p[x] != x) p[x] = find(p[x]); return p[x]; } int main() { cin>>n>>m>>vol; for(int i=1;i<=n;i++) p[i] = i; for(int i=1;i<=n;i++) cin>>v[i]>>w[i]; for(int i=0;i<m;i++) { int a,b; cin>>a>>b; int pa = find(a), pb = find(b); if(pa != pb) //两点没连一起 { v[pa] += v[pb]; w[pa] += w[pb]; p[pb] = pa; } } for(int i=1;i<=n;i++) if(p[i] == i) //根节点 for(int j=vol;j>=v[i];j--) f[j] = max(f[j], f[j - v[i]] + w[i]); cout<<f[vol]<<endl; }