圖論:Gale-Shapley算法


Gale-Shapley算法又叫做延遲認可算法,它可以解決這么一個問題

一共有N位男士和N位女士

每位男士對每位女士都有一個好感度,讓他們結合成為N對夫妻,要求男士優先表白,最后問結合情況

第一輪,每個男人都選擇自己名單上排在首位的女人,並向她表白。
這種時候會出現兩種情況:
(1)該女士還沒有被男生追求過,則該女士接受該男生的請求。
(2)若該女生已經接受過其他男生的追求,那么該女生會將該男士與她的現任男友進行比較,若更喜歡她的男友,那么拒絕這個人的追求,否則,拋棄現任……
第一輪結束后,有些男人已經有女朋友了,有些男人仍然是單身。
在第二輪追女行動中,每個單身男都從所有還沒拒絕過他的女孩中選出自己最中意的那一個,並向她表白,不管她現在是否是單身。
這種時候還是會遇到上面所說的兩種情況,還是同樣的解決方案。直到所有人都不在是單身。

以上給出了算法的描述,下面直接給出代碼,題目是POJ3487

由於這個問題沒有太大變式直接套模板就好了,如果要求女士優先,那就把男女身份互換然后再套用這個模板就好了

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<queue> 
 5 using namespace std;
 6 const int maxn=35;
 7 int n;
 8 int ml[maxn][maxn],fl[maxn][maxn],mc[maxn],fc[maxn];
 9 int mn[maxn],fn[maxn];
10 queue<int> q;  //沒有配對的男士 
11 int main()
12 {
13     int T;
14     char s[maxn];
15     scanf("%d",&T);
16     while(T--)
17     {
18         scanf("%d",&n);
19         //讀入男士的名字,初始化都沒有配對 
20         for(int i=0;i<n;i++)
21         {
22             scanf("%s",s);
23             mn[i]=s[0]-'a';
24             q.push(mn[i]);
25         }
26         //將名字排序 
27         sort(mn,mn+n);
28         for(int i=0;i<n;i++)
29         {
30             scanf("%s",s);
31             fn[i]=s[0]-'A';
32         }
33         //男士對女士的印象 
34         for(int i=0;i<n;i++)
35         {
36             scanf("%s",s);
37             for(int j=0;j<n;j++)
38                 ml[i][j]=s[j+2]-'A';
39         }
40         //女士對男士的打分,n號為初始對象 
41         for(int i=0;i<n;i++)
42         {
43             scanf("%s",s);
44             for(int j=0;j<n;j++)
45                 fl[i][s[j+2]-'a']=n-j;
46             fl[i][n]=0;
47         }
48         //一開始男士的期望都是最喜歡的女士 
49         memset(mc,0,sizeof(mc));
50         //女士先初始化一個對象 
51         for(int i=0;i<n;i++)
52             fc[i]=n;
53             while(!q.empty())
54             {
55                 //h=h%maxn+1;
56                 //找出一個沒有配對的男士 
57                 int m=q.front();
58                 //男士心怡的女士 
59                 int fm=ml[m][mc[m]];
60                 //如果當前男士比原來的男友好 
61                 if(fl[fm][m]>fl[fm][fc[fm]])
62                 {
63                     //脫單 
64                     q.pop();
65                     //否則考慮下一個對象 
66                     if(fc[fm]!=n)
67                     {
68                         q.push(fc[fm]);
69                         mc[fc[fm]]++;
70                     }
71                     //當前男友為這位男士 
72                     fc[fm]=m;
73                 }
74                 else mc[m]++;  //如果女士拒絕,考慮下一個對象 
75             }
76             for(int i=0;i<n;i++)
77                 printf("%c %c\n",mn[i]+'a',ml[mn[i]][mc[mn[i]]]+'A');
78             if(T) puts("");
79     }
80     return 0;
81 }

另外記住一點如果隊列不是特別正常的隊列不要手寫,還是STL比較穩


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM