uva 1175 Ladies' Choice (稳定婚姻问题)

uva 1175 Ladies’ Choice

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位女生,每人都对每个异性有一个排序,代表对他们的喜欢程度。你的任务是将男生和女生一一配对,使得男生u和女生v不存在以下情况:1)男生u和女生v不是舞伴。2)他们喜欢对方的程度都大于喜欢自己舞伴的程度,如果出现了2)中的情况,他们可能会抛下自己的舞伴,另外组成一组。你的任务是对于每个女生,在所有可能和他跳舞的男生中,找出他最喜欢的那个。
解题思路:经典的稳定婚姻问题。用求婚拒绝算法(Propose-and-reject algorithm)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

const int N = 1005;
typedef long long ll;
int n;
int men[N][N], getWifi[N], Next[N];
int women[N][N], getHus[N];
queue<int> Q;

void input() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &men[i][j]); //编号为i的男生第j喜欢的女生
        }
        Next[i] = 1; //编号为i的男生,下一个要邀请跳舞的对象
        getWifi[i] = 0; //编号为i的男生的舞伴编号
        Q.push(i);
    }
    int x;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &x);    
            women[i][x] = j; //编号为i的女生心目中,编号为x的男生的排名
        }
        getHus[i] = 0; //编号为i的女生的舞伴编号
    }
}

void engage(int man, int woman) {
    if (getHus[woman]) { //如果当前女生已经有了舞伴,那么为了更帅的新舞伴,抛弃他
        getWifi[getHus[woman]] = 0; //被抛弃的男生重新回到单身状态
        Q.push(getHus[woman]);
    }
    getHus[woman] = man; //新的一对
    getWifi[man] = woman;
}

void solve() {
    while (!Q.empty()) {
        int man = Q.front(); Q.pop();   
        int woman = men[man][Next[man]++];
        if (!getHus[woman]) { //如果当前女生单身,那直接配对
            engage(man, woman); 
        } else if (women[woman][man] < women[woman][getHus[woman]]) {
            //如果当前男生的排名在女生心目中比她舞伴的排名高,抛弃当前舞伴,和新的男生配对
            engage(man, woman); 
        } else Q.push(man); //悲剧的男生没人要,回炉重造
    }
    for (int i = 1; i <= n; i++) { //输出
        printf("%d\n", getWifi[i]); 
    }
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        while (!Q.empty()) Q.pop();
        input();    
        solve();
        if (T) puts("");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值