六度空間(MOOC)
阿新 • • 發佈:2018-11-02
六度空間:
“六度空間”理論又稱作“六度分隔(Six Degrees of Separation)”理論。這個理論可以通俗地闡述為:“你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多通過五個人你就能夠認識任何一個陌生人。”如圖1所示。
“六度空間”理論雖然得到廣泛的認同,並且正在得到越來越多的應用。但是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而由於歷史的原因,這樣的研究具有太大的侷限性和困難。隨著當代人的聯絡主要依賴於電話、簡訊、微信以及因特網上即時通訊等工具,能夠體現社交網路關係的一手資料已經逐漸使得“六度空間”理論的驗證成為可能。
假如給你一個社交網路圖,請你對每個節點計算符合“六度空間”理論的結點佔結點總數的百分比。
對每個結點輸出與該結點距離不超過6的結點數佔結點總數的百分比,精確到小數點後2位。每個結節點輸出一行,格式為“結點編號:(空格)百分比%”。
輸入格式:
輸入第1行給出兩個正整數,分別表示社交網路圖的結點數N( 1<N≤1 0 4 ,表示人數)、邊數M(≤33×N,表示社交關係數)。隨後的M行對應M條邊,每行給出一對正整數,分別是該條邊直接連通的兩個結點的編號(節點從1到N編號)。
輸出格式:
輸入樣例:
10 9 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10輸出樣例:
1: 70.00% 2: 80.00% 3: 90.00% 4: 100.00% 5: 100.00% 6: 100.00% 7: 100.00% 8: 90.00% 9: 80.00% 10: 70.00%
思路:圖的遍歷,此題因為是尋找距離數不超過6的結點,相當於尋找層數<6的結點。採用BFS,同時改造BFS返回一個節點數count。
遍歷過程中,採用傳統的BFS,建立佇列,同時寫出while迴圈結構。由於尋找層數<6的節點數,建立變數,節點數count,層數level,同時記錄
每一層最後一個結點last。當(level==6)跳出迴圈,返回結果。
接下來解決獲得last的方法:在每次入隊的同時,記錄tail=入隊的結點。
當記錄下來的入隊的結點tail和v相等時,last=tail,即將last更新為當層的最後一個結點,同時level++。
注意:1.輸出的結果為小數,用printf中的%.02f輸出結果。同時要將結果從int型轉換為double型。
2.每次輸出一個結點的所佔比百分數後,清空vis陣列的標記。
#include<cstdio> #include<queue> #include<cstring> using namespace std; int n,m; int G[10001][10001]; int vis[10001]; int BFS(int v){ vis[v]=1; queue<int> q; q.push(v); int count=1; //level 和last用於解決判斷層數的問題 level記錄層數,last記錄當前結點訪問的最後一個數 //問題是我們如何更新last,使得成為最後一個結點。 //這裡使用tail記錄出隊的結點,如果當前彈出的v==last,tail指向的結點一定是下一層的最後一個結點 int level=0,last=v,tail; while(!q.empty()){ int v=q.front(); q.pop(); for(int i=1;i<=n;i++){ //這個地方不是int i=0;i<n 注意! if(!vis[i]&&G[v][i]>0){ vis[i]=1; q.push(i); count++; tail=i; } } if(v==last){ level++;last=tail; } if(level==6)break; } return count; } int main(){ scanf("%d %d",&n,&m); int x,y; for(int i=0;i<m;i++){ scanf("%d %d",&x,&y); getchar(); G[x][y]=G[y][x]=1; } for(int i=1;i<=n;i++){ printf("%d: ",i); int count=BFS(i); //一定要強制轉換 double res=(double)count/(double)n*100; printf("%.2lf",res); printf("%\n"); memset(vis,0,sizeof(vis)); } }