N 頭牛(N≤100),M 場比賽結果(M≤4500),A B 表示 A 勝 B。技能值唯一且可傳遞(A>B, B=C ⇒ A>C)。求能唯一確定排名的牛的數量(即與其他所有 N-1 頭牛關系均已知)。
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 105;
bool g[MAXN][MAXN];
int in[MAXN], fa[MAXN];
int n, m;
int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]); }
void unite(int x, int y) { fa[find(x)] = find(y); }
int topo() {
queue q;
for (int i=1;i<=n;++i) if (in[i]==0) q.push(i);
int determined = 0;
while (!q.empty()) {
if (q.size() > 1) return determined; // 不唯一,後續也無法確定
int u = q.front(); q.pop();
++determined;
for (int v=1; v<=n; ++v) if (g[u][v]) {
if (--in[v] == 0) q.push(v);
}
}
return determined;
}
int main() {
while (~scanf("%d%d", &n, &m)) {
memset(g, 0, sizeof(g));
memset(in, 0, sizeof(in));
for (int i=1;i<=n;++i) fa[i]=i;
for (int i=0;i 1) { puts("0"); continue; }
printf("%d\n", topo());
}
return 0;
}
if (!g[a][b]) 避免重複計入入度。POJ 3660 結合並查集(判連通)與拓撲排序(判唯一性)解決「排名確定性」問題。關鍵洞察:
此模板適用於所有「偏序關系中可確定順序的元素計數」問題。