求稳定婚姻
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;
}