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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| #define int long long using namespace std;
const int N = 1e6 + 66;
int ver[N << 1], nex[N << 1], head[N], cnt;
inline void add_edge(int x, int y) { ver[++ cnt] = y; nex[cnt] = head[x]; return (void)(head[x] = cnt); }
int n, m, res, ret; int num, top, tot; int dfn[N], low[N], in[N], sta[N], tar[N], siz[N];
inline void tarjan(int x) { dfn[x] = low[x] = ++ tot; in[x] = 1, sta[++ top] = x; for (int i = head[x]; i; i = nex[i]) { int y = ver[i]; if (! dfn[y]) { tarjan(y); low[x] = min(low[x], low[y]); } else if (in[y]) low[x] = min(low[x], dfn[y]); } if (low[x] == dfn[x]) { ++ num; int y; do { y = sta[top --]; in[y] = 0; tar[y] = num; ++ siz[num]; }while (x != y); } return; }
queue<int>q; int rd[N], cd[N];
int vers[N], nexs[N], heads[N], cnts;
inline void add(int x, int y) { vers[++ cnts] = y; nexs[cnts] = heads[x]; ++ rd[y], ++ cd[x]; return (void)(heads[x] = cnts); }
int val[N];
inline int dfs(int x) { if (val[x]) return val[x]; int now = siz[x]; for (int i = heads[x]; i; i = nexs[i]) { int y = vers[i]; now = max(now, dfs(y) + siz[x]); } return val[x] = now; }
signed main() {
n = read(), m = read(); for (int i = 1; i <= m; ++ i) { int x = read(), y = read(); add_edge(x, y); }
for (int i = 1; i <= n; ++ i) if (! dfn[i]) tarjan(i);
for (int x = 1; x <= n; ++ x) { for (int i = head[x]; i; i = nex[i]) { int y = ver[i]; if (tar[x] == tar[y]) continue;
add(tar[x], tar[y]); } }
for (int i = 1; i <= num; ++ i) res = max(res, dfs(i)); put(res); return 0; }
|