zoukankan      html  css  js  c++  java
  • 「Codeforces」742D Arpa's weak amphitheater and Mehrdad's valuable Hoses (背包、并查集)

    题意:原题在这

    有n个人(1<=n<=1000)。每个人有一个重量wi(1<=wi<=1000)和一个魅力值bi(1<=bi<=10^6)。 n个人之间有m(1<=m<=min(n*(n-1)/2, 10^5))个关系。第i个关系由两个数字xi和yi组成,表示第xi个人和第yi个人是朋友,朋友关系是双向的。 已知若a和b是朋友,b和c是朋友,则a和c是朋友。 现在Mehrdad要邀请一些人来到派对,使这些人的重量总和不超过wi(1<=wi<=1000),且魅力值总和尽量大。同一个朋友圈里的人,只能邀请其中的一个人,或者全部人,或者一个人也不邀请。

    输入格式: 第一行,三个整数n,m,w 第二行,n个整数w1,w2,...,wn 第三行,n个整数b1,b2,...,bn 接下来m行,每行表示一个关系,第i行有两个整数xi和yi。每一组朋友关系都是不同的。

    输出格式: 一行,表示最大的魅力值总和。

    做法:

    1. 用并查集管理集合,开vector数组方便对集合进行遍历

    2. 把集合看成一件物品,因为要么从集合中取一个元素,要么取整个集合,那么就对这个集合中的每件物品背一次,然后对这件物品背一次。

    3.dp[i]表示当前重量为i的最大颜值,输出dp[maxweight]即可。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include<vector>
    #define inf 9999999999
    using namespace std;
    int n,m,weight;
    vector<int> vec[1005];
    int by[1005], wt[1005], fa[1005];
    long long dp[1005];
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    
    void unite(int x,int y)
    {
        fa[find(x)]=fa[find(y)];
    }
    
    int main()
    {
        cin>>n>>m>>weight;
        for(int i=1;i<=n;i++) cin>>wt[i];
        for(int i=1;i<=n;i++) cin>>by[i];
        for(int i=1;i<=n;i++) fa[i]=i;
        for(int i=0;i<m;i++)
        {
            int x;int y;
            cin>>x>>y;
            if(find(x)!=find(y)) unite(x, y);
        }
    
        for(int i=1;i<=n;i++) vec[find(i)].push_back(i);
        
        for(int i=1;i<=n;i++)
        {
            if(fa[i]==i)
            {
                for(int j=weight;j>=0;j--)
                {
                    int sumwt=0,sumby=0;
                    for(int k=0;k<vec[i].size();k++)
                    {
                        sumby+=by[vec[i][k]];
                        sumwt+=wt[vec[i][k]];
                        if(j>=wt[vec[i][k]]) dp[j]=max(dp[j],dp[j-by[vec[i][k]]]+by[vec[i][k]]);
                    }
                    if(j>=sumwt) dp[j]=max(dp[j],dp[j-sumwt]+sumby);
                }
            }
        }
        cout<<dp[weight]<<endl;
        return 0;
    }
  • 相关阅读:
    实验4 类的继承、派生和多态(1)
    期中
    实验3 类和对象
    设计、定义并实现Complex类
    android——fargment基础
    android——自定义listView
    android——HttpUrlConnection
    客户端与服务端小知识
    android——handler机制原理
    学习笔记——SQLite介绍
  • 原文地址:https://www.cnblogs.com/LocaEtric/p/9614566.html
Copyright © 2011-2022 走看看