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 }
非常开心在同学的帮助下解开了心结