hdu1435 稳定婚姻问题
題意:
? ? ? ? ? ? ? ?Stable Match
Special JudgeProblem Description Network 公司的BOSS 說現(xiàn)在他們公司建立的信號(hào)發(fā)射站和接收站經(jīng)常出現(xiàn)信號(hào)發(fā)送接收不穩(wěn)定的問題,信號(hào)的穩(wěn)定度被定義為發(fā)射點(diǎn)到接收點(diǎn)的距離,距離越大,越不穩(wěn)定,所以發(fā)射點(diǎn)跟接收點(diǎn)在可能的情況下應(yīng)越近越好.
BOSS給8600的任務(wù)就是::建立一個(gè)匹配表,使得一個(gè)發(fā)射點(diǎn)對(duì)應(yīng)一個(gè)接收點(diǎn),對(duì)于某一個(gè)發(fā)射點(diǎn)來說,它的接收點(diǎn)離它越近那么就會(huì)更穩(wěn)定,同樣對(duì)于接收點(diǎn)也是一樣的情況. 匹配的目標(biāo)是使得整個(gè)網(wǎng)絡(luò)變得穩(wěn)定。,對(duì)于某2個(gè)匹配,比如,( a ---- 1) ,(b----2) ,如果發(fā)射點(diǎn)a 離接收點(diǎn)2 比 1要近,而且2 也離 發(fā)射點(diǎn)a要比 b 近, 那么 a 就很有可能把信號(hào)發(fā)到 2中,我們就說這個(gè)搭配是不 穩(wěn)定的。同樣如果發(fā)射點(diǎn)b 離接收點(diǎn)1 比 2 要近,而且1 也離 發(fā)射點(diǎn)b要比 a 近 ,也會(huì)出現(xiàn)不穩(wěn)定的情 況. 而且每個(gè)點(diǎn)都有一個(gè)容量值,如果對(duì)于一個(gè)發(fā)射點(diǎn)到2個(gè)接收點(diǎn)的距離一樣的話,它將首先選擇容量大的那個(gè). 所以8600就是要建立一個(gè)穩(wěn)定的匹配,使得每個(gè)一個(gè)信號(hào)發(fā)射點(diǎn)對(duì)應(yīng)一個(gè)接收點(diǎn),并且不會(huì)出現(xiàn)信號(hào)不穩(wěn)定的情況.
8600苦思冥想也沒什么進(jìn)展,希望你能幫他解決這個(gè)難題.
Input 輸入數(shù)據(jù)首先包含一個(gè)正整數(shù)N,N<=20表示測試實(shí)例的個(gè)數(shù).每個(gè)實(shí)例首先是一個(gè)整C,C<=200表示有C個(gè)信號(hào)發(fā)射點(diǎn)和C個(gè)信號(hào)接收點(diǎn). 接下來的C行表示 C個(gè)發(fā)射點(diǎn)的編號(hào),容量和坐標(biāo),坐標(biāo)為,x,y,z 3個(gè)實(shí)數(shù)(x,y,z ≥0).最后C行是C個(gè)接收點(diǎn)的編號(hào),容量和坐標(biāo).
Output 輸出建立穩(wěn)定搭配后各個(gè)發(fā)射點(diǎn)和接收點(diǎn)的編號(hào),每一行代表一個(gè)搭配,前一個(gè)整數(shù)為發(fā)射點(diǎn)的編號(hào),后一個(gè)為對(duì)應(yīng)的接收點(diǎn)的編號(hào)。如果有多種情況,輸出其中一種即可.如果任務(wù)不可能完成的話,輸出"Impossible".每個(gè)實(shí)例后請輸出一個(gè)空行.
Sample Input 1 3 1 1 60.57 57.16 69.27 2 2 26.05 61.06 11.52 3 3 9.04 58.20 56.90 1 2 280.74 12.78 316.14 2 3 305.16 267.15 87.65 3 1 240.72 312.41 217.10
Sample Output 3 1 1 2 2 3
思路:
? ? ? 穩(wěn)定婚姻問題,先說明下,這個(gè)題目雖然是中文的,讀了好幾遍才讀懂,還有就是題目沒有敘述全吧,就是應(yīng)該加上 如果接受者面臨兩個(gè)距離一樣的發(fā)射者,那么他要選擇權(quán)值權(quán)值大的發(fā)射者,這個(gè)沒說,整的我以為發(fā)射者的權(quán)值沒用呢,后來排序的時(shí)候發(fā)現(xiàn)會(huì)有問題,自己加上去的,還有就是這個(gè)題目不存在 Impossible 的情況,因?yàn)榉€(wěn)定婚姻問題肯定有解的,然后就是細(xì)微的地方,去處理每個(gè)接受者在發(fā)射者心中的地位,和每個(gè)發(fā)射者在接受者心中的地位,然后就是穩(wěn)定婚姻問題了,下面我粘貼下我剛剛寫好的自己對(duì)穩(wěn)定婚姻的理解,本題用到的算法較容易實(shí)現(xiàn),所以我的是我自己手寫的,看著不舒服的可以去網(wǎng)上找找正規(guī)模板啥的。
穩(wěn)定婚姻問題就是給你n個(gè)男的,n個(gè)女的,然后給你每個(gè)男生中女生的排名,和女生心目中男生的排名,然后讓你匹配成n對(duì),使婚姻穩(wěn)定,假如a和b匹配,c和d匹配,如果a認(rèn)為d比b好,同時(shí)d也認(rèn)為a比c好,那么ad就有可能私奔,這樣就導(dǎo)致了婚姻的不穩(wěn)定,穩(wěn)定婚姻就是找到一種解決方案讓婚姻穩(wěn)定
算法:
? ? ? 穩(wěn)定婚姻的解決方法比較簡單,通俗易懂,而且還容易實(shí)現(xiàn),具體有沒有固定的模板我不知道,沒有去找,自己模擬的,在求解的過程中,我們先把所有的男生都加到隊(duì)列里,隊(duì)列里的就表示當(dāng)前還單身的男生,每次從隊(duì)列里拿出一個(gè)男生,然后從她最喜歡的女生開始匹配,如果當(dāng)前的女生嘗試追求過,那么就不用追求了,如果當(dāng)前的女生沒有伴侶,那么可以直接匹配上,如果有伴侶,那么就看看當(dāng)前這個(gè)男生和女生之前的伴侶在那個(gè)女生中更喜歡誰,如果更喜歡當(dāng)先的這個(gè)男生,那么當(dāng)前男生就和這個(gè)女生匹配,女生之前匹配過的直接變成單身,被扔回隊(duì)列,否則,繼續(xù)找下一個(gè)女生,知道找到一個(gè)能匹配上的為止,就這樣一直到隊(duì)列空的時(shí)候,就已經(jīng)全部匹配完成了。
正確性:
? ? ? ? 對(duì)于男生來說,每次都是從最喜歡的女生開始匹配的,遇到的第一個(gè)沒人能搶走的并且穩(wěn)定的就是自己最終伴侶,也就是說如果之前追求過的女生被別人搶走了,那么他將永遠(yuǎn)搶不會(huì)來,因?yàn)閷?duì)于女生來說,第一次被男士按照自己的意愿選擇之后,每次變更匹配對(duì)象都是在自己心目中更加喜歡的,所以一旦他放棄了某個(gè)男生,那么那個(gè)男生就沒希望在和他匹配,這樣男生是從最優(yōu)的選的,保證男生不會(huì)出軌,女生每次都是在選擇她的男生中選擇最優(yōu)的,這樣也保證了女生最后沒有怨言,這樣的話,最后的到的婚姻就是穩(wěn)定的,至于穩(wěn)定婚姻,肯定會(huì)有穩(wěn)定方案,這個(gè)我暫時(shí)證明不了.<1962年,美國數(shù)學(xué)家 David Gale 和 Lloyd Shapley是這兩個(gè)人發(fā)明的方法,并且證明了穩(wěn)定婚姻一定會(huì)有解>。
#include<queue> #include<math.h> #include<stdio.h> #include<string.h> #include<algorithm>#define N 200 + 5 using namespace std;typedef struct {int num ,v;double x ,y ,z; }NODE;typedef struct {double dis;int v ,id; }ZT;NODE node1[N] ,node2[N]; ZT zt[N]; int map[N][N] ,G_b[N][N]; int nowb[N] ,nowg[N]; int mark[N][N];bool camp(ZT a ,ZT b) {return a.dis < b.dis || a.dis == b.dis && a.v > b.v; }void Marr(int n) {queue<int>q;for(int i = 1 ;i <= n ;i ++)q.push(i);memset(mark ,0 ,sizeof(mark));memset(nowb ,255 ,sizeof(nowb));memset(nowg ,255 ,sizeof(nowg));while(!q.empty()){int xin ,tou = q.front();q.pop();for(int i = 1 ;i <= n ;i ++){xin = map[tou][i];if(mark[tou][xin]) continue;mark[tou][xin] = 1;if(nowg[xin] == -1){nowg[xin] = tou;nowb[tou] = xin;break;}else{if(G_b[xin][tou] > G_b[xin][nowg[xin]]){q.push(nowg[xin]);nowg[xin] = tou;nowb[tou] = xin;break;}}}}return; }double get_dis(NODE a ,NODE b) {double xx = (a.x - b.x) * (a.x - b.x);double yy = (a.y - b.y) * (a.y - b.y);double zz = (a.z - b.z) * (a.z - b.z);return xx + yy + zz; }int main () {int t ,n ,i ,j;scanf("%d" ,&t);while(t--){scanf("%d" ,&n);for(i = 1 ;i <= n ;i ++)scanf("%d %d %lf %lf %lf" ,&node1[i].num ,&node1[i].v ,&node1[i].x ,&node1[i].y ,&node1[i].z);for(i = 1 ;i <= n ;i ++)scanf("%d %d %lf %lf %lf" ,&node2[i].num ,&node2[i].v ,&node2[i].x ,&node2[i].y ,&node2[i].z);for(i = 1 ;i <= n ;i ++){for(j = 1 ;j <= n ;j ++){zt[j].dis = get_dis(node1[i] ,node2[j]);zt[j].v = node2[j].v;zt[j].id = j;}sort(zt + 1 ,zt + n + 1 ,camp);for(j = 1 ;j <= n ;j ++)map[i][j] = zt[j].id;}for(i = 1 ;i <= n ;i ++){for(j = 1 ;j <= n ;j ++){zt[j].dis = get_dis(node2[i] ,node1[j]);zt[j].v = node1[j].v;zt[j].id = j;}sort(zt + 1 ,zt + n + 1 ,camp);for(j = 1 ;j <= n ;j ++)G_b[i][zt[j].id] = n - j + 1;}Marr(n);for(i = 1 ;i <= n ;i ++)printf("%d %d\n" ,node1[i].num ,node2[nowb[i]].num);puts("");}return 0; }
總結(jié)
以上是生活随笔為你收集整理的hdu1435 稳定婚姻问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu1914 稳定婚姻问题
- 下一篇: POJ1236 强连通 (缩点后度数的应