# Description

Luogu 传送门

# Solution

(感谢 @Acestar 提供的思路)

初始情况下,每头奶牛匹配一个礼物,所以我们把奶牛和礼物当作一个点。

如果奶牛 ii 非常不要脸的去抢奶牛 jj 的礼物(iijj 连单向边),而且不幸的是奶牛 jj 还打不过奶牛 ii,那么 jj 就被迫去抢别人的礼物 qwq,所以 jj 就必须向它能抢到的别的奶牛连边。

因此我们这个图就建出来了,找一组解只需要跑一遍传递闭包即可,顺便拿个 bitset\text{bitset} 优化一下,时间复杂度 O(n3ω)O(\frac {n^3}\omega),跑的飞快。

# Code

@ShuKuang 已经成功卡到了目前最优解。

顺便感谢他提供的代码(

#include <bits/stdc++.h>
using namespace std;
namespace IO {
    template <typename T>
    inline void read(T &x) {
        x = 0; T r = 1;
        char ch = getchar();
        while (!isdigit(ch)) r = ch == '-' ? -1 : 1, ch = getchar();
        while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
        x *= r;
    }
    template <typename T, typename ...Args>
    void read(T &x, Args &...args) {
        read(x), read(args...);
    }
    template <typename T>
    inline void write(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
}
using namespace IO;
bitset<511> f[511];
short n;
short a[511][511];
signed main() {
    read(n);
    for (short i = 1; i <= n; ++ i) {
        for (short j = 1; j <= n; ++ j) {
            read(a[i][j]);
        }
    }
    for (short i = 1; i <= n; ++ i) {
        for (short j = 1; j <= n; ++ j) {
            if (a[i][j - 1] == i) break;
            f[i][a[i][j]] = 1;
        }
    }
    for (short j = 1; j <= n; ++ j) {
        for (short i = 1; i <= n; ++ i) {
            if (f[i][j]) 
                f[i] |= f[j];
        }
    }
    for (short i = 1; i <= n; ++ i) {
        for (short j = 1; j <= n; ++ j) {
            if (f[i][a[i][j]] && f[a[i][j]][i]) {
                write(a[i][j]), putchar('\n');
                break;
            }
        }
    }
}