ZOJ 1023 University Entrace Examination(稳定匹配变形)

来源:互联网 发布:百度云资源淘宝怎么搜 编辑:程序博客网 时间:2024/05/16 08:08

点击打开链接



这道题和最标准的稳定匹配不同的,就是男和女不是一个配一个,学生可能一个学校都不能去,但一个学校却有可能录取多个学生,其他都一样。所以原来的模板,只需要改动woman数组,就是这个程序中的Woman数组。为了方便,把学生看成男,把学校看成女,那么Woman数组中对于每一个女性,都要保存目前所选的学生,不断更新。这道题除了要求稳定性,还有一个隐含的要求就是不能够再找出一组男女搭配,加入到答案中还是不会出现私奔的情况。那么假设算法结束后,现在一个男性单身,他可以再找到一个女性组成这样的搭配,这个男性已经向所有的女性告白过了,包括现在将要和他搭配的女性,那么当时这个女人拒绝他就是因为名额已经满了并且都比他好,所以这个女性一定是没法和他在一起的,假设不成立。

关于cmp函数的写法要注意,return a > b就是降序排列,return a < b就是升序排列。
一般此类题都要写成结构体形式,然后有些时候每个人要自带一个编号,避免排序以后将顺序打乱。
这道题还有一个vis数组,在这题中Man出现0是允许的,只有在所有的男性都把女性告白一遍以后才停止。





#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<cmath>#include<algorithm>#define N 200using namespace std;struct node{    int region;    int score;    int num;    int sum;    int like[N];}man[N];struct node2{    int region;    int c;}woman[N];int T, n, m, flag, f, womanpos, y, r, maxx, numm;int ranke[N][N], ranks[N][N], tmpman[N], cnt[N], Man[N], Woman[N][N], vis[N];bool cmp(node a, node b){    if (a.region == r && b.region == r || a.region != r && b.region != r)    {        return a.score > b.score;    }    else        if (a.region == r && b.region != r)        {            return a.score > b.score*0.7;        }        else            {                return a.score*0.7 > b.score;            }}bool cmp2(node a, node b){    return a.num < b.num;}void sortrank(){    memset(ranks, 0, sizeof(ranks));    memset(ranke, 0, sizeof(ranke));    for (int i = 1; i <= n; i++)        for (int j = 1; j <= man[i].sum; j++)        ranks[i][j] = man[i].like[j];    for (int i = 1; i <= m; i++)    {        r = woman[i].region;        sort(man+1, man+n+1, cmp);        for (int j = 1; j <= n; j++)            ranke[i][man[j].num] = j;    }}void GS(){    memset(Man, 0, sizeof(Man));    memset(Woman, 0, sizeof(Woman));    memset(cnt, 0, sizeof(cnt));    memset(vis, 0, sizeof(vis));    for (int i = 1; i <= n; i++) tmpman[i] = 1;    sort(man+1, man+n+1, cmp2);    flag = 1;    while (flag)    {        flag = 0;        for (int i = 1; i <= n; i++)            if (Man[i] == 0 && vis[i] == 0)            {                flag = 1;                if (tmpman[i] > man[i].sum)                {                    vis[i] = 1;                    continue;                }                womanpos = ranks[i][tmpman[i]];                if (cnt[womanpos] < woman[womanpos].c)                {                    cnt[womanpos]++;                    Woman[womanpos][cnt[womanpos]] = i;                    tmpman[i]++;                    Man[i] = womanpos;                }                else                {                    maxx = ranke[womanpos][i];                    f = 0;                    for (int j = 1; j <= cnt[womanpos]; j++)                    {                        if (ranke[womanpos][Woman[womanpos][j]] > maxx)                        {                            f = 1;                            maxx = ranke[womanpos][Woman[womanpos][j]];                            numm = j;                        }                    }                    if (f == 1)                    {                        y = Woman[womanpos][numm];                        Woman[womanpos][numm] = i;                        Man[y] = 0;                        Man[i] = womanpos;                        tmpman[i]++;                    }                    else                        tmpman[i]++;                }            }    }}int main(){    scanf("%d", &T);    while (T--)    {        scanf("%d%d", &n, &m);        for (int i = 1; i <= n; i++)        {            man[i].num = i;            scanf("%d%d%d", &man[i].region, &man[i].score, &man[i].sum);            for (int j = 1; j <= man[i].sum; j++)                scanf("%d", &man[i].like[j]);        }        for (int i = 1; i <= m; i++)            scanf("%d%d", &woman[i].region, &woman[i].c);        sortrank();        GS();        for (int i = 1; i <= n; i++)            if (vis[i] == 1)            printf("not accepted\n");                else printf("%d\n", Man[i]);        if (T) printf("\n");    }    return 0;}

0 0
原创粉丝点击