洛谷P1455 搭配购买

#define  _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include<bits/stdc++.h>
#define int long long//防止数据过大
#define endl '\n'
using namespace std;
const int N = 100010;
int n, m, w;
int c[N], v[N],f[N],c1[N],v1[N];
bool vis[N];//标记这个点父节点的数据有没有被统计进去
int cnt=1;//辅助变量,遍历打包好的数据
int dp[N];
int find(int x)
{
    return f[x] == x ? x : f[x] = find(f[x]);//寻找f[x]的父节点,并把f[x]的上一级节点设为f[x]的父节点
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m >> w;
    for (int i = 1; i <= n; i++)
    {
        cin >> c[i] >> v[i];
        f[i] = i;//将每个节点的父节点设为自己
    }
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        cin >> y >> x;
        x = find(x);
        y = find(y);
        if (x == y)continue;
        f[x] = y;//将x的父节点设为y
        v[y] += v[x];//将两朵云彩的数据打包在一起,
        c[y] += c[x];
    }
    /*测试数据 1 3
    3 2
    就是说你买了1号,就要买3号,3号买了你还要买2号
    */
    for (int i = 1; i <= n; i++)
    {
        int x = find(i);
        if (!vis[i])
        {
            c1[cnt] += c[x];
            v1[cnt] += v[x];
            vis[x] = 1;//把这个点的父节点标为已统计
            cnt++;
        }
    }
    for (int i = 1; i <= cnt; i++)
    {
        for (int j = w; j >= c1[i]; j--)//因为当背包的容积小于物体的体积时就没法在加了
        {
            dp[j] = max(dp[j], dp[j - c1[i]] + v1[i]);//参考动画视频,或者手动模拟
        }
    }
    cout << dp[w];
    return 0;
}
 

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值