有點憂愁。\(CSP\)也考\(Tarjan\)縮點的嘛。c++
原理咱也不明白,咱也不敢學,找到模板就是抄。spa
#include<bits/stdc++.h> const int maxn = 10000; const int maxm = 100000; using namespace std; int to[maxm + 10]; int nex[maxm + 10]; int head[maxn + 10], cnt = 0; void addEdge(int a, int b) { to[cnt] = b; nex[cnt] = head[a]; head[a] = cnt++; } int low[maxn + 10], dfn[maxn + 10], sta[maxn + 10], belong[maxn + 10]; int index, top; int scc; bool inStack[maxn + 10]; int num[maxn + 10]; void Tarjan(int u) { int v; low[u] = dfn[u] = ++index; sta[top++] = u; inStack[u] = true; for (int i = head[u]; i != -1; i = nex[i]) { v = to[i]; if (!dfn[v]) { Tarjan(v); if (low[u] > low[v]) low[u] = low[v]; } else if (inStack[v] && low[u] > dfn[v]) low[u] = dfn[v]; } if (low[u] == dfn[u]) { scc++; do { v = sta[--top]; inStack[v] = false; belong[v] = scc; num[scc]++; } while (v != u); } } int main() { int n, m; scanf("%d%d", &n, &m); memset(head, -1, sizeof(head)); for (int i = 1, a, b; i <= m; i++) { scanf("%d%d", &a, &b); addEdge(a, b); } memset(dfn, 0, sizeof(dfn)); memset(inStack, false, sizeof(inStack)); memset(num, 0, sizeof(num)); index = scc = top = 0; for (int i = 1; i <= n; i++) { if (!dfn[i]) Tarjan(i); } int ans = 0; for (int i = 1; i <= scc; i++) { ans += num[i] * (num[i] - 1) / 2; } printf("%d\n", ans); return 0; }