L2-016 愿天下有情人都是失散多年的兄妹 CCCC
呵呵。大家都知道五服以內不得通婚,即兩個人最近的共同祖先如果在五代以內(即本人、父母、祖父母、曾祖父母、高祖父母)則不可通婚。本題就請你幫助一對有情人判斷一下,他們究竟是否可以成婚?
輸入格式:
輸入第一行給出一個正整數N(2 <= N <= 104),隨后N行,每行按以下格式給出一個人的信息:
本人ID 性別 父親ID 母親ID
其中ID是5位數字,每人不同;性別M代表男性、F代表女性。如果某人的父親或母親已經不可考,則相應的ID位置上標記為-1。
接下來給出一個正整數K,隨后K行,每行給出一對有情人的ID,其間以空格分隔。
注意:題目保證兩個人是同輩,每人只有一個性別,并且血緣關系網中沒有亂倫或隔輩成婚的情況。
輸出格式:
對每一對有情人,判斷他們的關系是否可以通婚:如果兩人是同性,輸出“Never Mind”;如果是異性并且關系出了五服,輸出“Yes”;如果異性關系未出五服,輸出“No”。
輸入樣例: 24 00001 M 01111 -1 00002 F 02222 03333 00003 M 02222 03333 00004 F 04444 03333 00005 M 04444 05555 00006 F 04444 05555 00007 F 06666 07777 00008 M 06666 07777 00009 M 00001 00002 00010 M 00003 00006 00011 F 00005 00007 00012 F 00008 08888 00013 F 00009 00011 00014 M 00010 09999 00015 M 00010 09999 00016 M 10000 00012 00017 F -1 00012 00018 F 11000 00013 00019 F 11100 00018 00020 F 00015 11110 00021 M 11100 00020 00022 M 00016 -1 00023 M 10012 00017 00024 M 00022 10013 9 00021 00024 00019 00024 00011 00012 00022 00018 00001 00004 00013 00016 00017 00015 00019 00021 00010 00011 輸出樣例: Never Mind Yes Never Mind No Yes No Yes No No 題解:要求五服以內不得通婚,那么判斷兩個異性是否在五服以內,只需要將他們各自五服以內的親人找出來,然后判斷是否有重復就好了,用bfs來尋找五服,當depth >= 4的時候直接結束循環就好了。判斷重復的方法可以是兩次bfs,然后把得到的5服放入set里面,看有沒有重復。當然還有更快的方法,就是我們先dfs第一個人的五服,在depth數組里,給他的五服以內親人打上標記,然后dfs第二個人,在dfs的過程中,如果遇到親人在depth已經被打上標記了,那么說明他倆是近親結婚,輸出No,否則,輸出Yes
思路很簡單,但是這個題目有坑,就是當要詢問的兩個有情人是某個人的父母,而不是單獨給出的時候,那么,用上述算法將得到錯誤的答案,因此為我們在讀入N個人的信息的時候,需要特殊處理一下,即當某個人的父母沒有單獨給出的時候,我們把f[父] = m[父] = -1;f[母] = m[母] =-1;經過這個處理以后,可以經過所有數據
#include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <queue> using namespace std; const int MAXN = 100005; int ext[MAXN]; int sex[MAXN],f[MAXN],m[MAXN]; int N; int depth[MAXN]; int main() {scanf("%d",&N);for(int i = 0;i < N;i++){int idf,idm,idi;char s;scanf("%d %c %d%d",&idi,&s,&idf,&idm);ext[idi] = 1;//idi是單獨給出的標志sex[idi] = s == 'F'?1:0;f[idi] = idf;if(idf != -1) {sex[idf] = 0;if(!ext[idf]) m[idf] = f[idf] = -1;//若父親沒有被單獨的給出,那么要默認設置父親的父母為-1}m[idi] = idm;if(idm != -1) {sex[idm] = 1; if(!ext[idm]) m[idm] = f[idm] = -1;}} int Q;scanf("%d",&Q);while(Q--){int a,b;scanf("%d%d",&a,&b);if(sex[a] == sex[b]){puts("Never Mind");continue;}else if(f[a] == b || m[a] == b || f[b] == a || m[b] == a){puts("No");continue;} else{memset(depth,0,sizeof(depth));queue<int> q;q.push(a);while(!q.empty()){int v = q.front();q.pop();if(depth[v] >= 4) break; //這樣五服內最高親屬下標就是4 if(m[v] != -1) {depth[m[v]] = depth[v] + 1;if(ext[m[v]]) q.push(m[v]);}if(f[v] != -1){depth[f[v]] = depth[v] + 1;if(ext[f[v]]) q.push(f[v]);} }while(!q.empty()) q.pop();q.push(b);int flag = 1;while(!q.empty()){int v = q.front();q.pop();if(depth[v] >= 4) break; if(depth[m[v]] || depth[f[v]]){flag = 0;break;}else{if(m[v] != -1) {depth[m[v]] = depth[v] + 1;if(ext[m[v]]) q.push(m[v]);}if(f[v] != -1){depth[f[v]] = depth[v] + 1;if(ext[f[v]]) q.push(f[v]);} }}if(flag) puts("Yes");else puts("No");}} } /* 3 1 M -1 -1 2 F 3 -1 4 M 3 -11 1 M 2 3 1 2 3 */。
總結
以上是生活随笔為你收集整理的L2-016 愿天下有情人都是失散多年的兄妹 CCCC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 礼品盒制作方法 礼品盒如何制作
- 下一篇: 苹果4铃声怎么设置 5步轻松设置铃声