六度空間
06-圖3 六度空間(30 分)
“六度空間”理論又稱作“六度分隔(Six Degrees of Separation)”理論。這個理論可以通俗地闡述為:“你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多通過五個人你就能夠認識任何一個陌生人。”如圖1所示。
圖1 六度空間示意圖
“六度空間”理論雖然得到廣泛的認同,並且正在得到越來越多的應用。但是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而由於歷史的原因,這樣的研究具有太大的局限性和困難。隨著當代人的聯絡主要依賴於電話、短信、微信以及因特網上即時通信等工具,能夠體現社交網絡關系的一手數據已經逐漸使得“六度空間”理論的驗證成為可能。
假如給你一個社交網絡圖,請你對每個節點計算符合“六度空間”理論的結點占結點總數的百分比。
輸入格式:
輸入第1行給出兩個正整數,分別表示社交網絡圖的結點數N(1<N≤10?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%
本來編程時,結果如下
測試點提示結果耗時內存
0 | sample 簡單一條鏈 | 答案正確 | 2 ms | 372KB |
1 | 不連通 | 答案正確 | 2 ms | 384KB |
2 | 一般圖 | 答案正確 | 2 ms | 372KB |
3 | 最小N和M | 答案正確 | 2 ms | 368KB |
4 | 最大N和M | 答案錯誤 | 1069 ms | 2628KB |
有點在回想我當初做這道題時,有哪些坑被我踩過。。這個BFS根據last來判斷是否結束的時候,出現了問題。目前是,如果發現一個點沒被訪問,就入隊,然後直到它被訪問,如果它剛好是下一個level的最後一個元素,碰到它了就認為這一層結束了。但是,一個結點是可能多次入隊的,比如2和3都是目前這一層,4都是它的子節點,那麽4就會入隊兩次,但不能一碰到4就認為下一層結束。所以在if(!visited)裏,就做個訪問標記,這樣的話別的父節點就不能使它入隊了。似乎我之前查這道題答案時還有看到節點裏有level的解法。
成功解決了該問題;改後結果如下:
測試點提示結果耗時內存
0 | sample 簡單一條鏈 | 答案正確 | 2 ms | 368KB |
1 | 不連通 | 答案正確 | 3 ms | 372KB |
2 | 一般圖 | 答案正確 | 2 ms | 368KB |
3 | 最小N和M | 答案正確 | 2 ms | 372KB |
4 | 最大N和M | 答案正確 | 515 ms | 2540KB |
1 #include<iostream> 2 3 #include<vector> 4 #include<queue> 5 #include<iomanip> 6 using namespace std; 7 #define maxvertexnum 10006 8 #define vertex int 9 vector<int> enqueue(maxvertexnum,0); 10 vector<int> visited(maxvertexnum,0); 11 struct adjnode{ 12 vertex v; 13 adjnode* next; 14 }; 15 using ptrtoadjnode=adjnode*; 16 struct edge{ 17 vertex v1,v2; 18 }; 19 using Edge=edge*; 20 struct vnode{ 21 ptrtoadjnode firstedge; 22 }; 23 using adjlist=vnode[maxvertexnum]; 24 struct graph{ 25 int Nv; 26 int Ne; 27 adjlist G; 28 }; 29 using Graph=graph*; 30 void Insert(Graph gra,Edge e){ 31 ptrtoadjnode newnode=new adjnode(); 32 newnode->v=e->v2; 33 newnode->next=gra->G[e->v1].firstedge; 34 gra->G[e->v1].firstedge=newnode; 35 newnode=new adjnode(); 36 newnode->v=e->v1; 37 newnode->next=gra->G[e->v2].firstedge; 38 gra->G[e->v2].firstedge=newnode; 39 } 40 Graph BuildGraph(){ 41 vertex v; 42 Graph gra=new graph(); 43 Edge e=new edge(); 44 cin>>gra->Nv>>gra->Ne; 45 for(v=1;v<=gra->Nv;v++) 46 gra->G[v].firstedge=NULL; 47 for(v=0;v<gra->Ne;v++){ 48 cin>>e->v1>>e->v2; 49 Insert(gra,e); 50 } 51 return gra; 52 } 53 int BFS(Graph gra,vertex v){ 54 queue<int> Q; int cnt=1; vertex v2; ptrtoadjnode ptr; 55 int last=v,tail,level=0; 56 Q.push(v); 57 visited[v]=1; 58 while(!Q.empty()){ 59 v=Q.front(); 60 Q.pop(); 61 visited[v]=1; 62 ptr=gra->G[v].firstedge; 63 while(ptr){ 64 v2=ptr->v; 65 ptr=ptr->next; 66 if(visited[v2]!=1&&enqueue[v2]==0){ 67 Q.push(v2); enqueue[v2]=1; cnt++; 68 tail=v2;} 69 } 70 if(last==v){ 71 ++level; last=tail; 72 } 73 if(level==6) 74 break; 75 } 76 for(auto &o:visited) 77 o=0; 78 for(auto &o:enqueue) 79 o=0; 80 return cnt; 81 } 82 void SDS(Graph gra){ 83 vertex v; double cnt; 84 for(v=1;v<=gra->Nv;v++){ 85 cnt=BFS(gra,v); 86 cnt=cnt/gra->Nv*100; 87 //cout<<v<<":"<<" "<<setiosflags(ios::fixed) 88 //<<setprecision(2)<<cnt<<"%"<<endl; 89 cout<<v<<":"<<" "; 90 printf("%.2lf",cnt); 91 cout<<"%"<<endl; 92 } 93 } 94 int main(){ 95 Graph gra=BuildGraph(); 96 SDS(gra); 97 return 0; 98 }View Code
非常開心在同學的幫助下解開了心結
六度空間