1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>

using namespace std;

void czytaj(vector<vector<int>> *A, int k, int n) {
    vector<int> a;
    a.resize(n, 0);
    (*A).push_back(a);
    a.clear();

    for(int i = 1; i < k; i++) {
        int N;
        scanf("%d", &N);
        for(int j=0; j < N; j++) {
            int pom;
            scanf("%d", &pom);
            a.push_back(pom);
        }
        (*A).push_back(a);
        a.clear();
    }
}

int rozwiaz(vector<vector<int>> A, int k) {
    int min = A[k-1].size();
    vector<int> ilePotrzeba;
    ilePotrzeba.resize(A[k-1].size(), 0);

    for(int i = k - 1; i >= 0 ; i--) {
        int aktMin = 0;
        for(size_t j = 0; j < A[i].size(); j++) { //aktualizujemy na obecnym poziomie ile potrzeba pracownikow
            aktMin += max(ilePotrzeba[j], 1); //jesli spotkanie jest kontynuowane to bierzemy ile potrzeba, inaczej jest nowe
        }
        min = max(min, aktMin);

        if(i > 0) {
            vector<int> ilePotrzebaObecnie;

            for(size_t j = 0; j < ilePotrzeba.size(); j++)
                ilePotrzebaObecnie.push_back(ilePotrzeba[j]);

            ilePotrzeba.assign(A[i-1].size(), 0);

            for(size_t j = 0; j < A[i].size(); j++)
                if(A[i][j] != 0) //jesli spotkanie jest kontynuacja jakiegos innego to
                    ilePotrzeba[A[i][j]-1] += max(ilePotrzebaObecnie[j], 1);

        }
    }

    return min;
}

int main() {
    int k, n;
    scanf("%d%d", &k, &n);

    vector<vector<int>> A;
    czytaj(&A, k, n);
    int min;
    min=rozwiaz(A, k);
    printf("%d\n", min);
    return 0;
}