zoukankan      html  css  js  c++  java
  • 打击犯罪

    【问题描述】

    某个地区有n(n<=1000)个犯罪团伙,当地警方按照他们的危险程度由高到低给他们编号为1-n,他们有些团伙之间有直接联系,但是任意两个团伙都可以通过直接或间接的方式联系,这样这里就形成了一个庞大的犯罪集团,犯罪集团的危险程度唯一由集团内的犯罪团伙数量确定,而与单个犯罪团伙的危险程度无关(该犯罪集团的危险程度为n)。现在当地警方希望花尽量少的时间(即打击掉尽量少的团伙),使得庞大的犯罪集团分离成若干个较小的集团,并且他们中最大的一个的危险程度不超过n/2。为达到最好的效果,他们将按顺序打击掉编号1到k的犯罪团伙,请编程求出k的最小值。 

    【输入格式】 
    第一行一个正整数n 
    接下来的n行每行有若干个正整数,第一个整数表示该行除第一个外还有多少个整数,若第i行存在正整数k,表示i,k两个团伙可以直接联系 

    【输出格式】 
    一个正整数,为k的最小值 

    【样例】 

    2 2 5 
    3 1 3 4 
    2 2 4 
    2 2 3 
    3 1 6 7 
    2 5 7 
    2 5 6 

    输出1(打击掉红色团伙) 

     

    思路

    简单的暴力+并查集的小小改动。。。

    反过来从全部集团都被干掉开始往前搜

    构造有n这个点时,判断与n相连的点是否存在,存在就合并+统计集合里点的数目,因为通过观察样例可以知道1和2有直接联系的话,那2和1也有直接联系,那么我们在只需要合并和统计与新构造的点相连的点就可以了

    然后如上构造n-1,n-2……直到新构造的点出现后的点集合有数目超过n div 2 就break然后输出答案

     1 program black;
     2 const
     3   inf='black.in';
     4   outf='black.out';
     5 var
     6   father,ok:array[0..1000] of longint;
     7   a:array[1..1000,0..1000] of longint;
     8   ch:array[1..1000] of boolean;
     9   i,n,t,sum,count,t1,t2,j:longint;
    10 
    11 function find(apple:longint):longint;
    12 begin
    13   if father[apple]<>0 then begin
    14                              father[apple]:=find(father[apple]);
    15                              exit(father[apple]);
    16                            end
    17   else exit(apple);
    18 end;
    19 
    20 procedure union(a,b:longint);
    21 begin
    22   t1:=find(a);
    23   t2:=find(b);
    24   if t1<>t2 then begin
    25                    father[t2]:=t1;
    26                    ok[t1]:=ok[t1]+ok[t2];
    27                    ok[t2]:=0;
    28                  end;
    29 end;
    30 
    31 begin
    32   assign(input,inf);
    33   assign(output,outf);
    34   reset(input); rewrite(output);
    35 
    36   readln(n);
    37   for i:= 1 to n do
    38     begin
    39       read(a[i,0]);
    40       for j:= 1 to a[i,0] do
    41         read(a[i,j]);
    42     end;
    43   count:=n+1;
    44   repeat
    45     dec(count);
    46     ch[count]:=true;
    47      j:=count; ok[j]:=1;
    48       for i:=1 to a[j,0] do
    49        if ch[a[j,i]] then
    50           union(j,a[j,i]);
    51     sum:=0;
    52     if ok[j]>n div 2 then break;
    53   until count=0;
    54 
    55   writeln(count);
    56 
    57   close(input);
    58   close(output);
    59 end.
  • 相关阅读:
    【面试题总结】第三篇
    Django 多账号登录
    Zabbix3.2 监控搭建
    2017.09.24校内训练
    2017.09.06校内训练
    tyvj P1001 第K极值
    洛谷P1020导弹拦截
    洛谷P1006传纸条
    2017.09.10校内训练
    hdu_1086 You can Solve a Geometry Problem too
  • 原文地址:https://www.cnblogs.com/bobble/p/6379896.html
Copyright © 2011-2022 走看看