• 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
  • 相关阅读:
    这次安装不太一样
    解惑C#不用释放内存(4)C#为何不用释放内存
    解惑C#不用释放内存(3)C++如何分配内存
    解惑C#不用释放内存(2)分配内存
    解惑C#不用释放内存(1)章节重点
    学习Java异常理解运行期异常
    学习Java声明异常throws
    学习java异常理解编译期异常
    学习java异常-前不久出现的问题
    学习java异常
  • 原文地址:https://www.cnblogs.com/yours1103/p/3351446.html
Copyright © 2020-2023  润新知