1. 程式人生 > >六度空間(MOOC)

六度空間(MOOC)

六度空間: “六度空間”理論又稱作“六度分隔(Six Degrees of Separation)”理論。這個理論可以通俗地闡述為:“你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多通過五個人你就能夠認識任何一個陌生人。”如圖1所示。 “六度空間”理論雖然得到廣泛的認同,並且正在得到越來越多的應用。但是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而由於歷史的原因,這樣的研究具有太大的侷限性和困難。隨著當代人的聯絡主要依賴於電話、簡訊、微信以及因特網上即時通訊等工具,能夠體現社交網路關係的一手資料已經逐漸使得“六度空間”理論的驗證成為可能。 假如給你一個社交網路圖,請你對每個節點計算符合“六度空間”理論的結點佔結點總數的百分比。

輸入格式:

 

輸入第1行給出兩個正整數,分別表示社交網路圖的結點數N( 1<N≤1 0 4 ,表示人數)、邊數M(≤33×N,表示社交關係數)。隨後的M行對應M條邊,每行給出一對正整數,分別是該條邊直接連通的兩個結點的編號(節點從1到N編號)。

輸出格式:

對每個結點輸出與該結點距離不超過6的結點數佔結點總數的百分比,精確到小數點後2位。每個結節點輸出一行,格式為“結點編號:(空格)百分比%”。

輸入樣例:

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));
  }
}