zoukankan      html  css  js  c++  java
  • 选学霸

    【题目描述】

    老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一部分没有,同学们就会抗议。所以老师想请你帮他求出他该选多少学霸,才能既不让同学们抗议,又与原来的M尽可能接近。

    【输入描述】

    第一行,三个正整数N、M、K;

    第2~K行,每行2个数,表示一对实力相当的人的编号(编号为1~N)。

    【输出描述】

    一行,表示既不让同学们抗议,又与原来的M尽可能接近的选出学霸的数目(如果有两种方案与M的差的绝对值相等,选较小的一种)。

    【样例输入】

    4 3 2

    1 2

    3 4

    【样例输出】

    2

    【数据范围及提示】

    100%的数据,N,P <= 30000。

    源代码:
    
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int m,n,k,Num(0),F[30001]={0};
    int V[30001],Belong[30001];
    bool f[30001];
    int Find(int t)
    {
        if (!F[t])
          return t;
        return F[t]=Find(F[t]);
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for (int a=1;a<=k;a++)
        {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            int T1=Find(t1);
            int T2=Find(t2);
            if (T1!=T2)
              F[T1]=T2;
        }
        for (int a=1;a<=n;a++) //并查集预处理。
        {
            int t=Find(a);
            if (!Belong[t])
            {
                V[++Num]=1;
                Belong[t]=Num;
            }
            else
              V[Belong[t]]++;
        }
        f[0]=true;
        for (int a=1;a<=Num;a++) //情况若能到达,便进行标记。
          for (int b=n;b>=V[a];b--)
            if (f[b-V[a]])
              f[b]=true;
        int Min=30000,ans;
        for (int a=0;a<=n;a++) //对于能够到达的情况便进行处理。
          if (f[a]&&abs(a-m)<Min)
          {
            Min=abs(a-m);
            ans=a;
          }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    ExcelHelper
    c# 文件的读写
    Wav文件操作类
    c# & (与) 、^ (异或)和 >>(<<位移运算)
    c# 高精度的timer
    c# 生成txt文件,写入内容
    C# 对 list<T>中的数据按某字段的大小进行排序
    OC 底层探索 06、 isa 2个经典问题分析
    OC 底层探索 05、属性、成员、实例变量简析
    数据结构与算法 0、 汇总简介
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5780158.html
Copyright © 2011-2022 走看看