csu1326
来源:互联网 发布:软件生命周期是指 编辑:程序博客网 时间:2024/05/16 04:47
背包的分组问题,详见背包九讲
用并查集分组、。、
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<vector>#include<algorithm>#include<time.h>#include<stdlib.h>#include<cmath>using namespace std;#define N 1005int F[N], vis[N];int W[N], P[N];int dp[N];vector<int>s[N];int find(int x){ if(x != F[x]) F[x] = find(F[x]); return F[x];}void Union(int x, int y){ int a = find(x); int b = find(y); if(a != b) F[b] = a;}int main(){ int n,Wmax,k; while(scanf("%d%d%d",&n,&Wmax,&k)!=EOF) { memset(vis, 0, sizeof(vis)); memset(dp, 0, sizeof(dp)); for(int i=0;i<=n;i++) { F[i]=i; s[i].clear(); } for(int i=1;i<=n;i++) scanf("%d%d",&P[i],&W[i]); for(int i=0;i<k;i++) { int a,b; scanf("%d%d",&a,&b); Union(a,b); } for(int i=1;i<=n;i++) { int a=find(i); s[a].push_back(i); } for(int i=1;i<=n;i++) { if(!s[i].size()) continue; for(int v=Wmax;v>=0;v--) { for(int k=0;k<s[i].size();k++) { int t=s[i][k]; if(v>=W[t]) dp[v]=max(dp[v],dp[v-W[t]]+P[t]); } } } printf("%d\n",dp[Wmax]); } return 0;}