关键是要明确在最坏情况下需要比较n * (n - 1) / 2次。
之后的事情就简单了,把已得到的两两关系算出来,然后看还差多少。O(nm)。
1 #include <cstdio>
2 #include <vector>
3 using namespace std;
4
5 const int N = 1000;
6
7 int n, m;
8 bool mk[N + 1];
9 vector<int> adj[N + 1];
10
11 int dfs(int u)
12 {
13 mk[u] = true;
14 int sum = 1;
15 for (vector<int>::iterator it = adj[u].begin(); it != adj[u].end(); ++it)
16 {
17 if (!mk[*it]) sum += dfs(*it);
18 }
19 return sum;
20 }
21
22 int main()
23 {
24 scanf("%d%d", &n, &m);
25 for (int i = 0; i < m; i++)
26 {
27 int a, b;
28 scanf("%d%d", &a, &b);
29 adj[a].push_back(b);
30 }
31
32 int cmp = 0;
33 for (int i = 1; i <= n; i++)
34 {
35 fill(mk + 1, mk + n + 1, false);
36 cmp += dfs(i) - 1;
37 }
38 printf("%d\n", n * (n - 1) / 2 - cmp);
39
40 return 0;
41 }
42
2 #include <vector>
3 using namespace std;
4
5 const int N = 1000;
6
7 int n, m;
8 bool mk[N + 1];
9 vector<int> adj[N + 1];
10
11 int dfs(int u)
12 {
13 mk[u] = true;
14 int sum = 1;
15 for (vector<int>::iterator it = adj[u].begin(); it != adj[u].end(); ++it)
16 {
17 if (!mk[*it]) sum += dfs(*it);
18 }
19 return sum;
20 }
21
22 int main()
23 {
24 scanf("%d%d", &n, &m);
25 for (int i = 0; i < m; i++)
26 {
27 int a, b;
28 scanf("%d%d", &a, &b);
29 adj[a].push_back(b);
30 }
31
32 int cmp = 0;
33 for (int i = 1; i <= n; i++)
34 {
35 fill(mk + 1, mk + n + 1, false);
36 cmp += dfs(i) - 1;
37 }
38 printf("%d\n", n * (n - 1) / 2 - cmp);
39
40 return 0;
41 }
42