Background
Teenagers from the local high school have asked you to help them with the organization of next year’s Prom. The idea is to find a suitable date for everyone in the class in a fair and civilized way. So, they have organized a web site where all students,
boys and girls, state their preferences among the class members, by ordering all the possible candidates. Your mission is to keep everyone as happy as possible. Assume that there are equal numbers of boys and girls.
Problem
Given a set of preferences, set up the blind dates such that there are no other two people of opposite sex who would both rather have each other than their current partners. Since it was decided that the Prom was Ladies‘ Choice, we want to produce the best
possible choice for the girls.
Input
Input consists of multiple test cases the first line of the input contains the number of test cases. There is a blank line before each dataset. The input for each dataset consists of a positive integer N, not greater than 1,000, indicating
the number of couples in the class. Next, there are N lines, each one containing the all the integers from 1 to N, ordered according to the girl’s preferences. Next, there are N lines, each one containing
all the integers from 1 to N, ordered according to the boy’s preferences.
Output
The output for each dataset consists of a sequence of N lines, where the i-th line contains the number of the boy assigned to the i-th girl (from 1 to N). Print a blank line between datasets.
Sample Input
1
5
1 2 3 5 4
5 2 4 3 1
3 5 1 2 4
3 4 2 1 5
4 5 1 2 3
2 5 4 1 3
3 2 4 1 5
1 2 4 3 5
4 1 2 5 3
5 3 2 4 1
Sample Output
1
2
5
3
4
题意:告诉n个男生和n个女生,让他们一起配对跳舞,他们都愿意和自己更喜欢的人一起跳舞。对于当前配对情况,A 和 C ,B 和 D,如果A喜欢B比喜欢C多,B喜欢A比喜欢D多,那么这两对就会被拆散,因为A和B都更愿意和对方在一起。那么,现在就要求怎样配对,才会是最稳定的。输入前n行为男生对女生的喜欢程度排序,后n行为女生对男生的喜欢程度排序。输出依次和n个男生配对的女生编号。
分析:这个问题涉及到婚姻稳定算法,这个算法也叫求婚-拒绝算法(Propose-and-reject algorithm)。这个算法的详细操作过程大概如下。有n对男女进行配对,对于每一轮操作,男士都去追求自己还没有追求过的最喜欢的女生,而女生可以选择答应或者拒绝,即使女生有了搭档,也是可以抛弃之前的,转而接受现在的。当所有人都配对成功之后,算法就可以结束。那么这个问题会不会出现有人没有搭档呢,答案是不会。如果有女生没有搭档的话,表明还没有人追求过她,然而,一个男生在放弃之前,是一定会先追求一遍所有的女生。因此可以保证每个人都能配对成功。
下面就要说一说这个配对方案的稳定性。对于当前配对情况,A 和 C ,B 和 D,如果A女生喜欢B男生比喜欢C多,同时B喜欢A也比喜欢D多,那么,B在和D在一起之前,一定先追求过A这个女生。然而女生每次在换对象的时候,一定是遇到了更好的。所以不会出现B比C更好的情况,同时,B之前已经被A拒绝了,那么D就是他现在觉得最好的。
虽然整个过程,都是女生选择男生,不断有男生被拒绝。然而这个游戏对男生确实最有利的。因为每个男生都有最大的可能和自己最喜欢的人在一起,除非对方拒绝了自己。然而女生却出于一种很被动的状态,因为自己最喜欢的人,可能从来没有追求过自己。所以,或许反过来,让所有的女生去追求选择男生,那么对于女生来讲也会更有利,她们有更多的机会和自己最喜欢的人一起。同样也不会影响算法的稳定性。
#include <iostream> #include <stdio.h> #include <string> #include <cstring> #include <cmath> #include <queue> using namespace std; queue<int>q;//单身男士队列 int manlike[1009][1009]; int womanlike[1009][1009]; int nt[1009];//男士下一个要选第几喜欢的人 int fwife[1009]; int fhusbond[1009]; int n; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); while(!q.empty()) q.pop(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) scanf("%d",&manlike[i][j]); q.push(i); nt[i]=1; fwife[i]=0; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int k; scanf("%d",&k); womanlike[i][k]=j;//女士对于编号为k的男士喜欢程度的排名 fhusbond[i]=0; } while(!q.empty()) { int man=q.front(); q.pop(); int woman=manlike[man][nt[man]]; nt[man]++; if(fhusbond[woman]==0) { fhusbond[woman]=man; fwife[man]=woman; } else if(womanlike[woman][man] < womanlike[woman][fhusbond[woman]]) { fwife[fhusbond[woman]]=0; q.push(fhusbond[woman]); fhusbond[woman]=man; fwife[man]=woman; } else q.push(man); } //cout<<"*******"<<endl; for(int i=1;i<=n;i++) printf("%d\n",fwife[i]); if(T>0) puts(""); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。