/* 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; } |
English