• csu 10月 月赛 I 题 The Contest


    Description

      殷犇有很多队员。他们都认为自己是最强的,于是,一场比赛开始了~

      于是安叔主办了一场比赛,比赛有n个题目,每个题目都有一个价值Pi和相对能力消耗Wi,但是有些题目因为太坑不能同时做出来,并且坑题具有传递性。(a和b一起做会坑、b和c会坑则a和c也会坑) ACM队员们想知道,于是他们想知道在能力范围内,它们最多可以作出多少价值的题目。

      聪明的你,告诉我,能帮帮他们吗?

    Input

      第1行两个整数,n,Wmax,k(0<=n,Wmax,k<=1000),其中n为题目总数,Wmax为初始的总能力数.

      接下来n行,为每个题目的Pi,Wi(0<=Pi<=1000,1<=Wi<=10,均为整数)

      再接下来k行,每行2个数字a,b表示a和b会坑

    Output

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

    Sample Input

    3 10 1 100 1 200 5 10 5 1 2

    Sample Output

    210

    HINT

      每个测试点1s


      CSU_WJQ

    Source

     
    并查集+多重背包
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define maxn 1005
     5 using namespace std;
     6  
     7 int f[maxn],value[maxn],consume[maxn],dp[maxn],zu[maxn];
     8 bool vis[maxn];
     9 int find(int x)
    10 {
    11     int tmp=x;
    12     while(x!=f[x])x=f[x];
    13     while(f[tmp]!=x)
    14     {
    15         int y=tmp;
    16         f[y]=x;
    17         tmp=f[tmp];
    18     }
    19     return x;
    20 }
    21  
    22 int main()
    23 {
    24     int n,w,k,x,y,a,b;
    25     while(scanf("%d%d%d",&n,&w,&k)!=EOF)
    26     {
    27         memset(dp,0,sizeof dp);
    28         memset(vis,0,sizeof vis);
    29         for(int i=1; i<=n; i++)
    30         {
    31             f[i]=i;
    32             scanf("%d%d",&value[i],&consume[i]);
    33         }
    34         for(int i=1; i<=k; i++)
    35         {
    36             scanf("%d%d",&x,&y);
    37             int a=find(x);
    38             int b=find(y);
    39             f[b]=a;
    40         }
    41         for(int i=1; i<=n; i++)
    42             find(i);
    43         int tot=0,mark;
    44         while(1)
    45         {
    46             for(int i=1; i<=n; i++)
    47             {
    48                 if(f[i]>0)
    49                 {
    50                     mark=f[i];
    51                     break;
    52                 }
    53             }
    54             for(int k=w; k>=0; k--)
    55                 for(int j=1; j<=n; j++)
    56                     if(f[j]==mark)
    57                     {
    58                         if(k>=consume[j])
    59                             dp[k]=max(dp[k],dp[k-consume[j]]+value[j]);
    60                     }
    61             for(int i=1; i<=n; i++)
    62                 if(f[i]==mark)
    63                 {
    64                     f[i]=0;
    65                     tot++;
    66                 }
    67             if(tot==n)break;
    68         }
    69         printf("%d
    ",dp[w]);
    70     }
    71 }
    View Code
  • 相关阅读:
    用PHP写一个最简单的解释器Part4(写一个最简单的脚本语言)
    Java 引用传递
    Java 收集的代码 transient
    Java 继承 执行顺序
    Java 静态类 static
    Java 多态 虚方法
    Mongodb 安装
    入手Intel 750
    Intellij IDEA 创建控制台项目,断点调试快捷方式
    IntelliJ IDEA 的 Java 热部署插件 JRebel 安装及使用
  • 原文地址:https://www.cnblogs.com/yours1103/p/3351446.html
Copyright © 2020-2023  润新知