Codevs P3372 选学霸

Codevs P3372 选学霸


题目描述 Description

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


输入输出


输入描述 Input Description

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

输出描述 Output Description

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


样例 Sample


样例输入 Sample Input

4 3 2
1 2
3 4

样例输出 Sample Output

2


数据范围及提示 Data Size & Hint

100%的数据N,P<=30000

分析

该题根据题目描述很显然是背包题,因为是要找与m差值绝对值最小的,所以有可能出现在m的左右两侧m个,所以扩大背包体积2倍进行背包,这样从m向左右两面找第一个装满即f[k]=k的背包,因为必须装满时的f[k]才等于人数,而未装满的则为前面装满的人数。

所以先并查集将一组的人合并,在进行2倍体积的01背包

代码如下

program p3372;
var volume,n,m,k,a,b,i,j:longint;
    num:array[1..1000] of longint;
    father:array[1..1000] of longint;
    f:array[0..1000] of longint;
function max(a,b:longint):longint;
begin
 if a>b then exit(a);
 exit(b);
end;

function find(x:longint):longint;
begin
 if father[x]=x
  then exit(x);
 father[x]:=find(father[x]);
 exit(father[x]);
end;

procedure union(a,b:longint);
begin
 father[find(father[b])]:=find(father[a]);
 num[find(father[a])]:=num[find(father[a])]+num[b];
 num[b]:=0;
end;

begin
 readln(n,m,k);
 for i:=1 to n do
  begin
   father[i]:=i;
   num[i]:=1;
  end;
 for i:=1 to k do
  begin
   readln(a,b);
   union(a,b);
  end;
 volume:=2*m;
 for i:=1 to n do
  begin
   if num[i]<>0
    then
     for j:=volume downto num[i] do
      begin
       f[j]:=max(f[j],f[j-num[i]]+num[i]);
      end;
  end;
 for i:=0 to m do
  begin
   if f[m-i]=m-i
    then
     begin
      write(m-i);
      break;
     end;
   if f[m+i]=m+i
    then
     begin
      write(m+i);
      break;
     end;
  end;
end.

评测结果

运行结果
测试点#study1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#study10.in 结果:AC 内存使用量: 492kB 时间使用量: 251ms
测试点#study2.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#study3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#study4.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#study5.in 结果:AC 内存使用量: 256kB 时间使用量: 4ms
测试点#study6.in 结果:AC 内存使用量: 256kB 时间使用量: 31ms
测试点#study7.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#study8.in 结果:AC 内存使用量: 368kB 时间使用量: 115ms
测试点#study9.in 结果:AC 内存使用量: 364kB 时间使用量: 147ms


快考试了。。。好担心。。


这里写图片描述
这里写图片描述


或许成永别.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值