[USACO08JAN] Cow Contest S

GitHub跳转原题关系图返回列表

用位集传递闭包统计每头牛已知强于和弱于的数量。

OJ: luogu

题目 ID: P2419

难度:普及

标签:传递闭包位运算偏序python

日期: 2026-07-17 03:00

题意

由比赛胜负关系判断有多少头牛的完整排名可以确定。

思路

胜者指向败者,位集 Warshall 求所有间接胜负。对牛 i,它能到达的数量加能够到达它的数量若为 n-1,说明与其他每头牛的强弱都已确定,排名唯一。

Python 知识

  • 一行可达集合编码成 Python 整数。
  • mask >> cow & 1 检查其他行是否能到达该牛。
  • 布尔值可直接参与整数求和。

代码

python
import sys


input = sys.stdin.buffer.readline
n, contests = map(int, input().split())
reachable = [0] * n
for _ in range(contests):
    winner, loser = map(int, input().split())
    reachable[winner - 1] |= 1 << (loser - 1)
for middle in range(n):
    bit = 1 << middle
    for start in range(n):
        if reachable[start] & bit:
            reachable[start] |= reachable[middle]
answer = 0
for cow in range(n):
    known = reachable[cow].bit_count() + sum(mask >> cow & 1 for mask in reachable)
    answer += known == n - 1
print(answer)

原有 C++ 版本仍保留:

cpp
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 100 + 5;

int n, m;
bool can_beat[MAXN][MAXN];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;

    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        can_beat[u][v] = true;
    }

    // Warshall 传递闭包:
    // 如果 i 能赢 k,k 又能赢 j,那么 i 也能赢 j。
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            if (!can_beat[i][k]) {
                continue;
            }
            for (int j = 1; j <= n; j++) {
                if (can_beat[k][j]) {
                    can_beat[i][j] = true;
                }
            }
        }
    }

    int answer = 0;

    for (int i = 1; i <= n; i++) {
        int known = 0;
        for (int j = 1; j <= n; j++) {
            if (i == j) {
                continue;
            }
            if (can_beat[i][j] || can_beat[j][i]) {
                known++;
            }
        }

        if (known == n - 1) {
            answer++;
        }
    }

    cout << answer << '\n';

    return 0;
}

复杂度

进行 O(n^2) 次位集 OR,空间 O(n^2) 位。

总结

排名可确定等价于该元素与所有其他元素都存在已知偏序关系。