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;
    }
  • 相关阅读:
    c#中获取服务器IP,客户端IP以及Request.ServerVariables详细说明
    无废话MVC入门教程二[第一个小Demo]
    winform使用xml作为数据源
    SQL Server 2005为数据库设置用户名和密码的方法
    数据库 的版本为 661,无法打开。此服务器支持 655 版及更低版本。不支持降级路径。
    Visual Studio快速封装字段方法
    erp crm oa
    sqldbhelper
    OleDbHelper
    存储过程分页(3)
  • 原文地址:https://www.cnblogs.com/LocaEtric/p/9614566.html
Copyright © 2011-2022 走看看