• codevs 5971 打击犯罪


    题目描述 Description

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

    输入描述 Input Description

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

    输出描述 Output Description

        一个正整数,为k的最小值

    样例输入 Sample Input

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

    样例输出 Sample Output

    1

    数据范围及提示 Data Size & Hint

    n<=1000

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

    解题思路

      这题的题意就是正向顺序删点1~K,使得每个集合的个数都不超过(n + 1) / 2,问最小的K是多少?
      正向顺序删点?感觉跟之前的 Hdu 4496 D-City 有点相像;
      如果正向顺序删点的话,那么每一次都需要重新维护并查集,所以我们可以逆向考虑,即从n~1开始枚举,将点加入图中,此时意味着删除了1 ~ K - 1,图还剩K ~ n;
      若此时剩下每个集合的个数还不超过(n + 1)/ 2,则继续逆向枚举,则到超过为止;

    代码如下

     1 #include<iostream>
     2 using namespace std;
     3 const int N = 1010;
     4 int f[N], a[N][N], sum[N], n;
     5 void init(){
     6     for(int i = 1; i <= n; i++){
     7         f[i] = i;
     8         sum[i] = 1;
     9     }
    10 }
    11 int getf(int x){
    12     if(x == f[x])    return x;
    13     else    return f[x] = getf(f[x]);
    14 }
    15 int main(){
    16     cin >> n;
    17     init();
    18     for(int i = 1; i <= n; i++){
    19         cin >> a[i][0];
    20         for(int j = 1; j <= a[i][0]; j++){
    21             cin >> a[i][j];
    22         }
    23     }
    24     for(int i = n; i >= 1; i--){    //逆向枚举 
    25         for(int j = 1; j <= a[i][0]; j++){
    26             if(a[i][j] > i){     //因为是顺序删除,所以删除该点时,那么之前的点已经删除了 
    27                 int t1 = getf(i), t2 = getf(a[i][j]);
    28                 if(t1 != t2){
    29                     f[t2] = t1;
    30                     sum[t1] += sum[t2];
    31                     if(sum[t1] > (n + 1) / 2){
    32                         cout << i << endl;
    33                         return 0;
    34                     }
    35                 }
    36             }
    37         }
    38     }
    39     return 0;
    40 }
    打击犯罪

  • 相关阅读:
    2021年2月4号
    2021年2月3号
    2021年2月2号
    2021年2月1日
    2021年1月31日
    2021年1月30日
    20171205xlVBA往返航班组合
    选择文件
    从VBA过渡到Python
    20171114xlVba选定单行记录并打印
  • 原文地址:https://www.cnblogs.com/zoom1109/p/11052024.html
Copyright © 2020-2023  润新知