题解。
贪心,拓扑排序。
和拓扑排序一样,先把$flag$为$0$的点能删的都删光,露出来的肯定都是$flag$为$0$的,然后疯狂删$flag$为$0$的,这些会使答案加$1$,反复操作就可以了。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int n, m; int f[maxn], in[maxn]; int h[maxn], to[maxn], nx[maxn]; void add(int id, int u, int v) { to[id] = v; nx[id] = h[u]; h[u] = id; in[v] ++; } int main() { scanf("%d%d", &n, &m); for(int i = 0; i < n; i ++) { h[i] = -1; scanf("%d", &f[i]); } for(int i = 0; i < m; i ++) { int u, v; scanf("%d%d", &u, &v); add(i, v, u); } queue<int> Q[2]; for(int i = 0; i < n; i ++) { if(in[i] == 0) { Q[f[i]].push(i); } } int cnt = 0; int ans = 0; while(cnt != n) { if(!Q[0].empty()) { while(!Q[0].empty()) { int x = Q[0].front(); cnt ++; Q[0].pop(); for(int i = h[x]; i != -1; i = nx[i]) { in[to[i]] --; if(in[to[i]] == 0) { Q[f[to[i]]].push(to[i]); } } } } else { ans ++; while(!Q[1].empty()) { int x = Q[1].front(); cnt ++; Q[1].pop(); for(int i = h[x]; i != -1; i = nx[i]) { in[to[i]] --; if(in[to[i]] == 0) { Q[f[to[i]]].push(to[i]); } } } } } printf("%d\n", ans); return 0; }