zoj 1023

来源:互联网 发布:淘宝开放平台登录授权 编辑:程序博客网 时间:2024/06/06 14:11

求稳定婚姻
n个学生有所属地域,分数,偏爱的学校数量,偏爱的学校
m个学校所属地域,学校招收人数

对于每个学生,偏爱的学校按照顺序
对于每个学校,在相同区域下,肯定喜欢分数高的,基于区域保护制度,外地(x)学生的分数会打七折进行比较

问每个学生的录取情况


把学生当做男生求爱,学校是可以接受多份情书的女生(x)
改一下原有的一对一的情况
更新女生的匹配情况,把当前最不喜欢的驱逐
蛮好理解的


错在cmp上,西湖的水 わだしの 泪
(现在自己对cmp的理解是,默认升序的情况下,return的情况为是否满足自己定义的a < b )


#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <queue>#include <algorithm>const int maxn=510;struct points{  int region,score,num,like_num,like[maxn],cap;}boy[maxn],girl[maxn];int n,reg,m;int vis[maxn],nowb[maxn],nowg[maxn][maxn],mark[maxn][maxn],g_pre[maxn][maxn],b_pre[maxn][maxn],cntg[maxn];using namespace std;bool cmp1(const points &xx,const points &yy){  return xx.num<yy.num;}void Gale_Shapley(){  int i,gir,now,j;  queue<int>q;  sort(boy+1,boy+n+1,cmp1);  for(i=1;i<=n;i++) q.push(i);   memset(nowb,0,sizeof(nowb));   memset(nowg,0,sizeof(nowg));   memset(mark,0,sizeof(mark));   memset(vis,0,sizeof(vis));   memset(cntg,0,sizeof(cntg));   while (!q.empty())   {    now=q.front(); q.pop();    vis[now]++;    if (vis[now]>boy[now].like_num) continue;    int  flag=0;    for (i=1;i<=boy[now].like_num;i++)    if (!mark[now][i])      {        mark[now][i]=1;        gir=b_pre[now][i];        if (cntg[gir]<girl[gir].cap)        {          cntg[gir]++;          nowg[gir][cntg[gir]]=now;          nowb[now]=gir;          flag=1;        }        else if (!flag)        {          int maxx=g_pre[gir][now];          for (j=1;j<=cntg[gir];j++)          if (g_pre[gir][nowg[gir][j]]>maxx)          {            flag=j;            maxx=g_pre[gir][nowg[gir][j]];          }          if (!flag) q.push(now);          else          {            int th=nowg[gir][flag];            nowg[gir][flag]=now;            nowb[th]=0;            nowb[now]=gir;            q.push(th);          }        }        break;      }   }}bool cmp(const points &xx,const points &yy){  if (xx.region==reg && yy.region==reg) return xx.score>yy.score;  if (xx.region!=reg && yy.region!=reg) return xx.score>yy.score;  if (xx.region==reg && yy.region!=reg) return xx.score*10>yy.score*7;  if (yy.region==reg && xx.region!=reg) return xx.score*7>yy.score*10;}void cz(){    int i,j;      memset(b_pre,0,sizeof(b_pre));      memset(g_pre,0,sizeof(g_pre));      for (i=1;i<=n;i++)        for (j=1;j<=boy[i].like_num;j++)          b_pre[i][j]=boy[i].like[j];        for (i=1;i<=m;i++)        {          reg=girl[i].region;         // printf("reg=%d\n",reg);          sort(boy+1,boy+n+1,cmp);          for (j=1;j<=n;j++)           {               // printf("i=%d j=%d\n",i,boy[j].num);              //  printf("j region=%d score=%d\n",boy[j].region,boy[j].score);                g_pre[i][boy[j].num]=j;           }        }  Gale_Shapley();      for (i=1;i<=n;i++)        if (nowb[i]) printf("%d\n",nowb[i]);        else printf("not accepted\n");}int main(){    int cases,i,j;    scanf("%d",&cases);    while (cases--)    {     scanf("%d%d",&n,&m);      for (i=1;i<=n;i++)      {        boy[i].num=i;        scanf("%d%d%d",&boy[i].region,&boy[i].score,&boy[i].like_num);        for (j=1;j<=boy[i].like_num;j++) scanf("%d",&boy[i].like[j]);      }    for (i=1;i<=m;i++) scanf("%d%d",&girl[i].region,&girl[i].cap);      cz();    if (cases) printf("\n");    }    return 0;}

顺便存一下以前自己搞的模板好了

*Mark数组表示是否处理过
B_pre[][i]表示男孩偏好的第i个女孩编号
G_pre[][i]表示女孩对比好为i的男孩的偏好值(数组越小表示越优先)
nowb nowg则表示当前的匹配情况*

#include <iostream>#include <cstdio>#include <cstring>#include <map>#include <queue>const int maxn=510;int n;int nowb[maxn],nowg[maxn],mark[maxn][maxn],g_pre[maxn][maxn],b_pre[maxn][maxn];using namespace std;void Gale_Shapley(){    int i,gir,now;    queue<int>q;    for(i=1;i<=n;i++) q.push(i);   memset(nowb,0,sizeof(nowb));   memset(nowg,0,sizeof(nowg));   memset(mark,0,sizeof(mark));   while (!q.empty())   {    now=q.front(); q.pop();    for (i=1;i<=n;i++)        if (!mark[now][i])        {            mark[now][i]=1;            gir=b_pre[now][i];            if (nowg[gir]==0 || g_pre[gir][now]<g_pre[gir][nowg[gir]])            {              //  printf("%d %d %d\n",now,gir,nowg[gir]);                if (nowg[gir]) q.push(nowg[gir]);                nowb[nowg[gir]]=0;                nowg[gir]=now;                nowb[now]=gir;                break;            }        }   }}int main(){    map<string,int>boy_name,girl_name;    char ss[300],bs[maxn][30],gs[maxn][30];    int i,j;    while (~scanf("%d",&n))    {        boy_name.clear();        girl_name.clear();        memset(b_pre,0,sizeof(b_pre));        memset(g_pre,0,sizeof(g_pre));        for (i=1;i<=n;i++)        {            scanf("%s",ss);            boy_name[ss]=i;            strcpy(bs[i],ss);            for (j=1;j<=n;j++)            {                scanf("%s",ss);                if (i==1)  { girl_name[ss]=j; strcpy(gs[j],ss); }                b_pre[i][j]=girl_name[ss];            }        }        int wz;        for (i=1;i<=n;i++)        {            scanf("%s",ss);            wz=girl_name[ss];            for (j=1;j<=n;j++)            {                scanf("%s",ss);                g_pre[wz][boy_name[ss]]=j;            }        }        Gale_Shapley();        for (i=1;i<=n;i++)            printf("%s %s\n",bs[i],gs[nowb[i]]);    }    return 0;}
原创粉丝点击