题目链接:https://www.luogu.com.cn/problem/P2002
思路:由于图中每个强连通分量(scc)中的点是可以互相到达的,所以我们可以用tarjan求图中scc,然后将所有scc缩点,最后求缩点之后图中入度为0的点的个数就是答案。
代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<vector>
4 #include<map>
5 #include<queue>
6 #include<set>
7 #include<algorithm>
8 #include<stack>
9 #include<cmath>
10 #include<cstring>
11 #include<string>
12 using namespace std;
13 #define gc getchar()
14 #define rd(x) read(x)
15 #define el '\n'
16 #define rep(i, a, n) for(int i = (a); i <= n; ++i)
17 #define per(i, a, n) for(int i = (a); i >= n; --i)
18 using ll = long long;
19 using db = double;
20 using ldb = long double;
21 const int mod = 1e9 + 7;
22 const int inf = 0x3f3f3f3f;
23 const int N = 100000 + 10;
24
25 template <typename _T>
26 inline void read(_T& f) {
27 f = 0; _T fu = 1; char c = gc;
28 while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = gc; }
29 while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = gc; }
30 f *= fu;
31 }
32
33 template <typename T>
34 void print(T x) {
35 if (x < 0) putchar('-'), x = -x;
36 if (x < 10) putchar(x + 48);
37 else print(x / 10), putchar(x % 10 + 48);
38 }
39
40 template <typename T>
41 void print(T x, char t) {
42 print(x); putchar(t);
43 }
44
45 int dfn[N], low[N], ins[N], scc[N], in[N];
46 int dfncnt, scccnt;
47 stack<int>st;
48 vector<int>G[N];
49 vector<int>DAG[N];
50
51 int n, m;
52 int pmax;
53
54 void tarjan(int u) {
55 dfn[u] = ++dfncnt;
56 low[u] = dfncnt;
57 st.push(u);
58 ins[u] = true;
59 for (int i = 0; i < G[u].size(); i++) {
60 int v = G[u][i];
61 if (!dfn[v]) {
62 tarjan(v);
63 low[u] = min(low[u], low[v]);
64 }
65 else if (ins[v]) {
66 low[u] = min(low[u], dfn[v]);
67 }
68 }
69 if (dfn[u] == low[u]) {
70 int v;
71 ++scccnt;
72 pmax = max(pmax, scccnt);
73 do {
74 v = st.top();
75 st.pop();
76 ins[v] = false;
77 scc[v] = scccnt;
78 } while (u != v);
79 }
80 }
81
82 void getdag() {
83 for (int i = 1; i <= n; i++) {
84 if (!dfn[i]) {
85 tarjan(i);
86 }
87 }
88 for (int u = 1; u <= n; u++) {
89 for (int j = 0; j < G[u].size(); j++) {
90 int v = G[u][j];
91 if (scc[u] != scc[v]) {
92 DAG[scc[u]].push_back(scc[v]);
93 in[scc[v]]++;
94 }
95 }
96 }
97 }
98
99 int main() {
100
101 ios::sync_with_stdio(false);
102 cin.tie(0), cout.tie(0);
103 //int n, m;
104 cin >> n >> m;
105 for (int i = 1; i <= m; i++) {
106 int u, v;
107 cin >> u >> v;
108 G[u].push_back(v);
109 }
110 getdag();
111 int ans = 0;
112 for (int i = 1; i <= pmax; i++) {
113 if (!in[i]) ans++;
114 }
115 cout << ans << el;
116
117 return 0;
118 }