專題訓練3-圖論 - L - Cow Contest (Floyd最短路)
阿新 • • 發佈:2022-03-28
題意
FJ的N(1 <= N <= 100)頭奶牛們最近參加了場程式設計競賽:)。在賽場上,奶牛們按1..N依次編號。每頭奶牛的程式設計能力不盡相同,並且沒有哪兩頭奶牛的水平不相上下,也就是說,奶牛們的程式設計能力有明確的排名。 整個比賽被分成了若干輪,每一輪是兩頭指定編號的奶牛的對決。如果編號為A的奶牛的程式設計能力強於編號為B的奶牛(1 <= A <= N; 1 <= B <= N; A != B) ,那麼她們的對決中,編號為A的奶牛總是能勝出。 FJ想知道奶牛們程式設計能力的具體排名,於是他找來了奶牛們所有 M(1 <= M <= 4,500)輪比賽的結果,希望你能根據這些資訊,推斷出儘可能多的奶牛的程式設計能力排名。比賽結果保證不會自相矛盾。
輸入格式
第1行: 2個用空格隔開的整數:N 和 M 第2..M+1行: 每行為2個用空格隔開的整數A、B,描述了參加某一輪比賽的奶 牛的編號,以及結果(編號為A,即為每行的第一個數的奶牛為 勝者)
輸出格式
第1行: 輸出1個整數,表示排名可以確定的奶牛的數目
樣例
Input | Output |
---|---|
5 5 4 3 4 2 3 2 1 2 2 5 |
2 |
思路
若“A勝B且B勝C”,則“A勝C”。
首先,用floyd演算法將每兩頭奶牛的勝負關係確定。
然後,分別判斷每一頭牛是否與其他每一頭牛都確定了勝負關係(邊數 == n-1),若是,則計數器加一。
程式碼
#include <cstring> #include <iostream> using namespace std; const int N = 105; const int inf = 1e9; int n, m; bool M[N][N]; int num[N]; // 統計頂點i的鄰接頂點數(邊數) void floyd() { for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (M[i][k] && M[k][j]) M[i][j] = true; } int main() { scanf("%d %d", &n, &m); memset(M, false, sizeof M); while (m--) { int a, b; scanf("%d %d", &a, &b); M[a][b] = true; } floyd(); int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (M[i][j] || M[j][i]) num[i]++; } if (num[i] == n - 1) ans++; } printf("%d\n", ans); return 0; }