xtu1146 Boys and Girls 简单模拟

#include <stdio.h>
#include <string.h>
int main()
{
 int i,j,n,k,boy[105][105],girl[105][105],tem[105][105],bans[105];
 int bfree[105],gfree[105],count[105],match[105][105];

 while (scanf("%d",&n) != EOF){
  for(i = 0;i <= n;i++){
  bfree[i] = 1;gfree[i] = 1;//free[] = 1 代表单身 0 已婚
  bans[i] = 0;
  girl[i][0] = 1000;
  }
  
  for(i = 1; i <= n;i++)//方便起见令数组下标对应相应的序数
  for(j = 1; j <= n;j++)
   scanf("%d",&boy[i][j]); // 第i个boy的第j喜欢的女孩
  for(i = 1; i <= n;i++)
  for(j = 1; j <= n;j++)
   scanf("%d",&tem[i][j]); // 第i个女孩的第j喜欢的男孩
  // 令 girl[i][j] 代表第i个女孩心目中第j个男孩的排名 方便后面在O(1)内比较出选哪个男孩是最优的
  for(i = 1; i <= n;i++)
  for(j = 1; j <= n;j++){
   k = tem[i][j];
   girl[i][k] = j;
  }
  //进行很多轮配对,直到全部配完,跳出循环
  while(1){
   for(i = 0;i <= n;i++)
    count[i] = 0;
   memset(match,0,sizeof(match));
   int flag = 0;//作为判断是否配完的标志

   for(i = 1;i <= n;i++){
    if ( bfree[i] == 0 ) continue;
    for(j = 1;j <= n ;j++){
     k = boy[i][j];
     if (gfree[k] == 1){// 找到剩下的单身女孩中男生最喜欢的那个
     count[k]++;
     match[k][i] = 1;
     break;//记录下第i个男孩这轮中最喜欢的女孩k
     }
    }
   }
   for(i = 1;i <= n;i++){//判断第i个女孩在这轮中与哪个男孩配对
    int min = 0;
    if (count[i] == 0) continue;
    if (count[i] == 1){
     for(j = 1;j <= n;j++)
      if (match[i][j] == 1){
       bans[j] = i;
       bfree[j] = 0;
       gfree[i] = 0;
       break;
      }
    }
    else{
     for(j = 1;j <= n;j++){
      if (match[i][j] == 1){
       min = girl[i][min] < girl[i][j] ? min : j;
      }
     }
     bans[min] = i;
     bfree[min] = 0;
     gfree[i] = 0;
    }
   }
   for(i = 1;i <= n;i++){
    if (gfree[i] != 0) flag = 1;
   }
   if (flag == 0) break;
  }
  for(i = 1;i < n;i++)
   printf("%d ",bans[i]);
  printf("%d\n",bans[i]);
 }
 return 0;
}

你可能感兴趣的:(xtu1146 Boys and Girls 简单模拟)