/* ODCINANIE OD LIŚCI * * wywalamy wierzchołki bez kraw wychodzących dopoki sie da * jak sie nie da to udajemy ze jakis wierzcholek ich nie ma * slowa kluczowe : toposort, silnie spojne składowe * * while (jest wierzcholek z jedna krawedzia wychodzaca) scal go */ #include <iostream> #include <vector> #include <queue> #include <algorithm> #include <cassert> using namespace std; int n, l, a, ss, st[200005], poz[200005], stos[200005]; vector<int> v[200005]; long long wynik[200005]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> l; for (int j = 0; j < l; j++) { cin >> a; st[i]++; v[a].push_back(i); } } for (int i = 1; i <= n; i++) poz[i] = i; for (int i = 1; i <= n; i++) { vector<int> tmp; stos[ss++] = i; while (ss > 0) { int x = stos[--ss]; for (int out: v[x]) { st[out]--; if (out != i) { tmp.push_back(out); poz[out] = max(poz[x], poz[out]); if (!st[out]) { stos[ss++] = out; wynik[poz[out]]++; } } else { st[out]++; } } } poz[i] = i; for (int x: tmp) st[x]++, poz[x] = x; } for (int i = 1; i <= n; i++) { wynik[i] += wynik[i-1]; cout << wynik[i] << ' '; } cout << endl; }
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 66 | /* ODCINANIE OD LIŚCI * * wywalamy wierzchołki bez kraw wychodzących dopoki sie da * jak sie nie da to udajemy ze jakis wierzcholek ich nie ma * slowa kluczowe : toposort, silnie spojne składowe * * while (jest wierzcholek z jedna krawedzia wychodzaca) scal go */ #include <iostream> #include <vector> #include <queue> #include <algorithm> #include <cassert> using namespace std; int n, l, a, ss, st[200005], poz[200005], stos[200005]; vector<int> v[200005]; long long wynik[200005]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> l; for (int j = 0; j < l; j++) { cin >> a; st[i]++; v[a].push_back(i); } } for (int i = 1; i <= n; i++) poz[i] = i; for (int i = 1; i <= n; i++) { vector<int> tmp; stos[ss++] = i; while (ss > 0) { int x = stos[--ss]; for (int out: v[x]) { st[out]--; if (out != i) { tmp.push_back(out); poz[out] = max(poz[x], poz[out]); if (!st[out]) { stos[ss++] = out; wynik[poz[out]]++; } } else { st[out]++; } } } poz[i] = i; for (int x: tmp) st[x]++, poz[x] = x; } for (int i = 1; i <= n; i++) { wynik[i] += wynik[i-1]; cout << wynik[i] << ' '; } cout << endl; } |