NOIP 提高组 2010 关押罪犯

71 篇文章 0 订阅
30 篇文章 0 订阅

题目大意:

S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S城Z市长那里。公务繁忙的Z市长只会去看列表中的第一个事件的影响力,如果影响很坏,他就会考虑撤换警察局长。
在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。
那么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是多少?

题解:

排序+并查集:
这题我们分析可得要求的是最大的冲突最小是多少
怎么做呢?
先将其的怨恨度大到小排序,
然后做并查集
对于一组罪犯i,j如果他们放到不同监狱中跟之前冲突了,那么他们的冲突影响肯定是答案
因为如果不让他们2个冲突,那么比他们大的冲突影响就会冲突
判断过程用并查集去存即可。

代码:

var
     a:array [0..100001,1..3] of longint;
     f:array [0..40001] of longint;
     i,j,p,q,n,m:longint;

procedure qsort(l,r:longint);
var
     i,j,mid:longint;
begin
     if l>=r then exit;
     mid:=a[(l+r) div 2,3];
     i:=l; j:=r;
     repeat
          while a[i,3]>mid do inc(i);
          while a[j,3]<mid do dec(j);
          if i<=j then
          begin
                a[0]:=a[i];
                a[i]:=a[j];
                a[j]:=a[0];
                inc(i); dec(j);
          end;
     until i>j;
     qsort(i,r);
     qsort(l,j);
end;

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

begin
      readln(n,m);
      for i:=1 to m do
        begin
             for j:=1 to 3 do read(a[i,j]);
             readln;
        end;
      qsort(1,m);

      for i:=1 to 2*n do f[i]:=i;
      for i:=1 to m do
         begin
               p:=find(a[i,1]);
               q:=find(a[i,2]);
               f[p]:=find(a[i,2]+n);
               f[q]:=find(a[i,1]+n);
               if p=q then
               begin
                  writeln(a[i,3]);
                  halt;
               end;
         end;
      writeln(0);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值