题目描述:给你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;
}