[Solution] title fight against crime

Title Description

        Certain areas n (n≤1000) criminal gangs, local police according to their degree of danger to them from high to low numbered from 1 to n, there is a direct link between gangs ,, but some of them can be any two groups contact directly or indirectly, so here is formed a huge crime, the degree of risk criminal group is uniquely determined by the number of criminal gangs within the group, but not with the degree of risk of a single criminal gangs regardless of the degree of risk (the criminal group to n). Local police now want to spend as little time (ie, blow out as little as possible of the gang), so that a large criminal group separated into several smaller groups, and the degree of risk they are no more than a maximum of n / 2. For best results, they will be out of order to combat criminal gangs numbered 1 to k, please obtain the minimum value of k program.

 

Input Format

        The first line, a positive integer n.

        The next n lines, each line has a number of positive integers, the first integer except the first row there is an integer number, if there is a positive integer k i-th row, i represents, two groups may be directly k contact.

 

Output Format

        A positive integer, the minimum value of 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

 

Sample Description

        Output 1 (the fight against criminal gangs)

        Failed to load picture

 

answer

        We can reverse enumeration, enumeration from $ n $ to $ 1 $.

        When we enumerate $ I $, we meet the combined $ i <j $ side $ (i, j) $, determines whether the combined current collection points where greater than $ I $ $ \ frac {n} { 2} $ can.

#include <iostream>
#include <cstdio>

#define MAX_N (1000 + 5)

using namespace std;

int n;
int a[MAX_N][MAX_N], l[MAX_N];
int r[MAX_N], c[MAX_N];

int Root(int x)
{
    int R = x, tmp;
    while(R != r[R]) R = r[R];
    while(x != r[x]) tmp = r[x], r[x] = R, x = tmp;
    return R;
}

void Merge(int x, int y)
{
    x = Root(x); 
    y = Root(y);
    r[x] = y;
    c[y] += c[x];
    c[x] = 0;
    return;
}

int main()
{
    scanf("%d", &n);
    for(register int i = 1; i <= n; ++i)
    {
        scanf("%d", l + i);
        for(register int j = 1; j <= l[i]; ++j)
        {
            scanf("%d", a[i] + j);
        }
    }
    for(register int i = 1; i <= n; ++i)
    {
        r[i] = i;
        c[i] = 1;
    }
    for(register int i = n; i; --i)
    {
        for(register int j = 1; j <= l[i]; ++j)
        {
            if(i > a[i][j]) continue;
            if(Root(i) != Root(a[i][j])) Merge(i, a[i][j]);
            if(c[Root(i)] > (n >> 1)) return printf("%d", i), 0;
        }
    }
    return 0;
}
Reference program

 

Guess you like

Origin www.cnblogs.com/kcn999/p/10990524.html