zoj Marriage is Stable
题意就是稳定婚姻问题。
如果男A与女C匹配,男B与女D 匹配,但是A更喜欢D,D更喜欢A,那么这个婚姻就不是稳定的。稳定婚姻问题的算法步骤大致如下:(男士优先)
1.男士先选择自己最爱的人去求婚,如果有多个男士的最爱相同,那么女士就选择更爱的那位男士,那么其他的男士在这次求婚中失败。
2.上次求婚失败的男士再选择自己次爱的女士进行求婚,如果这位女士没有匹配男士,那么这两个人就进行匹配,如果这位女士有匹配的男士,但是如果这位女士更喜欢这位正在求婚的男士,那么这位女士就可以抛弃原有的男士而与这位她更爱的男士匹配。而原有的男士在这次匹配中失败。
3.上次求婚失败的男士(包括被女士抛弃的男士)再次选择自己次爱的女士求婚,知道所有的男士与女士全部匹配则结束。
次算法被证明必定存在解,刚才所写的步骤是基于男士优先的。如果是女士向男士求婚,那么就是基于女士优先的,算法步骤和上面的基本相同,只要将男女调换就可以了。
const int maxn=510;
int n;
int boy[maxn][maxn];//男人的爱好 boy[i][0]-boy[i][n-1]//递减记录男生喜欢的女生
int girl[maxn][maxn];//女生的爱好
int bm[maxn];//标记男生喜欢的女生
int que[maxn*maxn];//装载着要重新找男生的女生的队列
int st=0,ed=0;
for(int i=0;i<n;++i)//男生选他最喜欢的女生,女生入队
{
bm[i]=boy[i][boy[i][n]++];
que[ed++]=i;
}
while(st<ed)
{
int i=que[st++];
bool flag=0;
for(int j=0;j<n;++j)//枚举女生喜欢的男生
{
int k=girl[i][j];
if(bm[k]==i)//该男生刚好也想跟这个女生结婚
{
if(flag==0)//找到了第一个想跟她结婚的男生
flag=1;//标记第一个找到了
else//拒绝其他人
{
bm[k]=boy[k][boy[k][n]];//找下一个女生
que[ed++]=boy[k][boy[k][n]++];//将这个女生入队
}
}
}
}