1. 程式人生 > 其它 >專題訓練3-圖論 - L - Cow Contest (Floyd最短路)

專題訓練3-圖論 - L - Cow Contest (Floyd最短路)

題意

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;
}