题目描述:给你n个小姐姐的重量和颜值,而且给你几组关系x,y表示x认识y ,现在要邀请她们吃饭,总共邀请的小姐姐的重量不能大于w (可能怕桌子会跨~~) 且互相认识的小姐姐要么最多邀请一个要么全部邀请
现在想问你邀请来的小姐姐颜值最高是多少
分析:显然是个分组背包,顶多在加个并差集分组的过程(先分堆,在标记她们的堆,然后分别加入vector里)
ac代码:
#include<bits/stdc++.h> using namespace std; int pa[10003]; int n,m,w; int dp[1003]; int b[1004],ww[1003]; int find(int x){ if(pa[x]!=x) pa[x]=find(pa[x]); return pa[x]; } int main(){ // freopen("1.txt","r",stdin); cin>>n>>m>>w; map<int,int> ha; int top=0; vector<vector<int> >group(1004); memset(ww,0,sizeof ww); memset(b,0,sizeof b); for(int i=0;i<=n;i++)pa[i]=i; for(int i=1;i<=n;i++)cin>>ww[i]; for(int i=1;i<=n;i++)cin>>b[i]; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; int x1=find(x),y1=find(y); if(x1!=y1) pa[x1]=y1; } for(int i=1;i<=n;i++){ int now=find(i); if(ha.find(now)==ha.end())ha[now]=top++; } for(int i=0;i<=top;i++)group[i].push_back(0); for(int i=1;i<=n;i++)group[ha[pa[i]]].push_back(i); // for(int i=0;i<top;i++){ // for(int j=0;j<group[i].size();j++) cout<<group[i][j]; // cout<<endl; // } memset(dp,0,sizeof(dp)); for(int i=0;i<top;i++){ for(int j=w;j>=0;j--){ int bb=0,www=0; for(int k=0,sz=group[i].size();k<sz;k++){ bb+=b[group[i][k]],www+=ww[group[i][k]]; if(j-ww[group[i][k]]>=0)dp[j]=max(dp[j],dp[j-ww[group[i][k]]]+b[group[i][k]]); } if(j-www>=0)dp[j]=max(dp[j],dp[j-www]+bb); } } int ma=0; for(int i=0;i<=w;i++)ma=max(dp[i],ma); cout<<ma<<endl; }