拓扑排序。
#include<cstdio> #include <iostream> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn = 100000 + 10; int T, n, m; bool flag[maxn]; struct Edge { int u, v; int nx; }e[maxn]; int tot; int head[maxn]; int cnt[maxn]; int L[maxn]; int f; void init() { tot = 0; memset(cnt, 0, sizeof cnt); memset(head, -1, sizeof head); memset(flag, 0, sizeof flag); } void add(int a, int b) { ++tot; e[tot].u = a; e[tot].v = b; e[tot].nx = head[a]; head[a] = tot; } void read() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); cnt[v]++; } } void Sort() { priority_queue<int>Q; f = 0; for (int i = 1; i <= n; i++) if (cnt[i] == 0) Q.push(i); while (!Q.empty()) { int h = Q.top(); Q.pop(); L[f++] = h; for (int i = head[h]; i != -1; i = e[i].nx) { cnt[e[i].v]--; if (cnt[e[i].v] == 0) Q.push(e[i].v); } } long long ans = L[0]; long long Min = L[0]; for (int i = 1; i < f; i++) { Min = min(Min,(long long) L[i]); ans = ans + Min; } printf("%lld ", ans); } int main() { scanf("%d", &T); while (T--) { init(); read(); Sort(); } return 0; }