• vijos1250 最勇敢的机器人


    背景

    Wind设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了~

    描述

    机器人们都想知道谁是最勇敢的,于是它们比赛搬运一些物品。

    它们到了一个仓库,里面有n个物品,每个物品都有一个价值Pi和重量Wi,但是有些物品放在一起会爆炸,并且爆炸具有传递性。(a和b会爆炸、b和c会爆炸则a和c会爆炸)
    机器人们可不想因此损失自己好不容易从Wind那里敲诈来的装备,于是它们想知道在能力范围内,它们最多可以拿多少价值的物品。

    你能帮助它们吗?

    格式

    输入格式

    每组测试数据
    第1行为n,Wmax,k(0<=n,Wmax,k<=1000)
    接下来n行,为每个物品的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均为整数)
    再接下来k行,每行2个数字a,b表示a和b会发生爆炸

    输出格式

    对每组数据输出1行
    为最大可能价值

    样例1

    样例输入1[复制]

     
    3 10 1
    100 1
    200 5
    10 5
    1 2

    样例输出1[复制]

     
    210
    /*
    并查集分组,分组背包
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn = 1005;
    struct ITM{
        int v;
        int w;
    }temp;
    int n,c,k,f[maxn],v[maxn],w[maxn],dp[maxn];
    int u1,u2,r;
    int cnt,tran[maxn],now;
    bool vis[maxn];
    vector<ITM> itm[maxn];
    int findf(int x){
        return x == f[x] ? x : f[x] = findf(f[x]);
    }
    int read(){
        char ch=getchar();
        int f=1,x=0;
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    int main(){
        n = read();
        c = read();
        k = read();
        for(int i = 1;i <= n;i++) f[i] = i;
        for(int i = 1;i <= n;i++){
            v[i] = read();
            w[i] = read();
        }
        for(int i = 1;i <= k;i++){
            u1 = read();
            u2 = read();
            u1 = findf(u1);
            u2 = findf(u2);
            if(u1 != u2) f[u1] = u2;
        }
        for(int i = 1;i <= n;i++){
            r = findf(i);
            temp.v = v[i];
            temp.w = w[i];
            itm[r].push_back(temp);
            if(!vis[r]){
                vis[r] = true;
                cnt++;
                tran[cnt] = r;
            }
        }
        for(int i = 1;i <= cnt;i++){
            now = tran[i];
            for(int j = c;j >= 0;j--){
                for(int t = 0;t < itm[now].size();t++){
                    if(j >= itm[now][t].w)dp[j] = max(dp[j],dp[j-itm[now][t].w] + itm[now][t].v);
                }
            }
        }
        cout<<dp[c];
        return 0;
    }
  • 相关阅读:
    洛谷P3674 小清新人渣的本愿
    洛谷P3709 大爷的字符串
    CF747F Igor and Interesting Numbers
    洛谷P1494 小Z的袜子
    洛谷P3396 哈希冲突
    分块⑨题
    洛谷P4219 大融合
    bzoj2959 长跑
    洛谷P2486 染色
    洛谷P4382 劈配
  • 原文地址:https://www.cnblogs.com/hyfer/p/5893821.html
Copyright © 2020-2023  润新知