稳定婚姻问题简单的说就是
男的不停求婚女的不停拒绝
然后都选择当且最喜欢的作为pair
本题的话把行,数字看成男女
行喜欢本行中靠左的
数字喜欢在所有行出现位置最靠右的行
观察如下的情况
i: xxxxxxxxxxxxx
j: x vvvv
此时不合法
因为j-x喜欢的程度大于i-x
复杂度\(O(nmT)\)
#include <bits/stdc++.h>
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
x = 0; char c = getchar(); bool f = 0;
for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
if(f) x = -x;
}
namespace one {
const int N = 256;
int n, m, a[N][N], mp1[N][N], mp2[N][N], idx[N][N];
int d[N], c[N], has[N], tmp[N];
inline void init(void) {
for(int i = 0; i <= n; i ++)
for(int j = 0; j <= n; j ++)
mp1[i][j] = mp2[i][j] = idx[i][j] = d[j] = c[j] = has[j] = tmp[j] = 0;
}
inline void doit(void) {
queue<int> q; fo(i, n) q.push(i);
while(!q.empty()) {
int u = q.front(); q.pop();
++ has[u];
int nxt = mp1[u][has[u]];
if(!d[nxt] || mp2[nxt][u] < mp2[nxt][d[nxt]]) {
if(d[nxt]) q.push(d[nxt]);
c[d[nxt]] = 0;
d[nxt] = u; c[u] = nxt;
}
else if(has[u] != n) q.push(u);
}
for(int i = 1; i <= n; i ++)
cout << c[i] << " ";
puts("");
}
void main(void) {
read(n); read(m);
init();
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
int t; read(t);
if(t) mp1[i][++ mp1[i][0]] = t;
if(t) idx[i][t] = j;
}
}
fo(i, n) {
fo(j, n) tmp[j] = j;
sort(tmp + 1, tmp + n + 1, [&](int a, int b) {
return idx[a][i] > idx[b][i];
});
fo(j, n) mp2[i][tmp[j]] = j;
}
doit();
}
}
main(void) {
int T; for(read(T); T --; one::main());
}