题意:稳定婚姻问题。
分析:
od(i, j)表示编号为i的女士心目中,编号为x的男士的排名。
pf(i, j)表示编号为i的男士第j喜欢的人。
f(0, i)表示编号为i的女士的未婚夫,f(1, i)表示编号为i的男士的未婚妻。
nxt(i)表示编号为i的男士下一个求婚对象的排名。
q队列里存着所有未订婚的男士。
这题输入有些奇怪,小心一点就是了。
然后用站在女性角度考虑好像不符合题目要求,得站在男性角度考虑,白白WA一次。
这题代码就没有什么难理解的地方了。
#include <cstdio> #include <queue> #include <algorithm> using namespace std; const int N = 30; char str[N], name[N*2]; int T, n, x, od[N][N], pf[N][N], nxt[N], f[2][N]; queue<int> q; void date(int x, int y) { int m = f[0][y]; if(m) f[1][m] = 0, q.push(m); f[1][x] = y, f[0][y] = x; } int main() { scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 1; i <= n*2; i++) scanf("%s", str), name[i] = str[0]; sort(name+1, name+n+1); for(int i = 1; i <= n; i++) { scanf("%s", str); for(int j = 2; j < n+2; j++) pf[str[0]-'a'+1][j-1] = str[j]-'A'+1; nxt[str[0]-'a'+1] = 1, f[1][str[0]-'a'+1] = 0; q.push(str[0]-'a'+1); } for(int i = 1; i <= n; i++) { scanf("%s", str); for(int j = 2; j < n+2; j++) od[str[0]-'A'+1][str[j]-'a'+1] = j-1; f[0][str[0]-'A'+1] = 0; } while(!q.empty()) { int u = q.front(); q.pop(); int v = pf[u][nxt[u]++]; if(!f[0][v]) date(u, v); else if(od[v][u] < od[v][f[0][v]]) date(u, v); else q.push(u); } for(int i = 1; i <= n; i++) printf("%c %c\n", name[i], f[1][name[i]-'a'+1]+'A'-1); if(T) printf("\n"); } return 0; }