「Codeforces 1131D」Gourmet Choice
阿新 • • 發佈:2021-08-07
Description
美食家 Apple 先生是一家美食雜誌的主編。他會用一個正整數來評價每一道菜。
美食家在第一天品嚐第 $n$ 道菜,第二天品嚐了 $m$ 道菜。他製作了一張 $n\times m$ 的表格,記錄了他對菜餚的評價。如果第一套中的第 $i$ 道菜比第二套中的第 $j$ 道菜好,那麼 $a_{i,j}$ 等於 `>`;如果要差,那麼 $a_{i,j}$ 等於 `<`。菜餚可能同樣美味,那麼 $a_{i,j}$ 等於 `=`。
現在 Apple 先生想讓你幫他評價每道菜。由於他是非常嚴格的,他會對菜餚進行評估,以便使用的最大整數儘可能小。但是 Apple 先生也很公平,如果 $a_{i,j}$ 為 `<`,那麼給第一套中第 $i$ 道菜的評價一定小於第二套中第 $j$ 道菜。如果 $a_{i,j}$ 是 `>` 那麼應該要更大。如果 $a_{i,j}$ 為 `=`,那麼這兩個數字要相等。
幫助 Apple 先生評價這兩套中的每一道菜,使之符合他的感受,並滿足最大數字儘可能小。如果有解則輸出 `Yes` 和評價的數字;否則輸出 `No`。
資料範圍:$1\le n,m\le 10^3$。
首先我們把 =
給處理掉,把所有相等的點縮在一起。如果同一個並查集中的點有 <
或 >
關係顯然無解。
此時我們得到了一個有向圖,直接對它拓撲排序,如果有環則無解,否則輸出方案。
const int N = 2e3 + 10; vector<int>e[N]; string s[N]; int f[N], p[N], d[N]; int find(int x) {return x == f[x] ? x : f[x] = find(f[x]);} int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, m; cin >> n >> m; for (int i = 0; i < n; ++i) cin >> s[i]; for (int i = 0; i < n + m + 1; ++i) f[i] = i; for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (s[i][j] == '=') { int u = find(i), v = find(n + j); f[u] = v; } for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) if (s[i][j] != '=') { int u = find(i), v = find(n + j); if (s[i][j] == '<') { e[u].push_back(v); d[v] += 1; } else { e[v].push_back(u); d[u] += 1; } } queue<int>q; for (int i = 0; i < n + m; ++i) if (find(i) == i and !d[i])q.push(i), p[i] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int v : e[u]) if (!(--d[v])) { q.push(v); p[v] = p[u] + 1; } } for (int i = 0; i < n + m; ++i) if (!(p[i] = p[find(i)])) {cout << "No\n"; return 0;} cout << "Yes\n"; for (int i = 0; i < n; ++i) cout << p[i] << " \n"[i == n - 1]; for (int i = 0; i < m; ++i) cout << p[i + n] << " "; }
The desire of his soul is the prophecy of his fate
你靈魂的慾望,是你命運的先知。