中国大学MOOC-数据结构基础习题集、05-3、六度空间
题目链接:http://www.patest.cn/contests/mooc-ds/05-3
题目分析:这是一道考察图的广度优先遍历的一道题,题目的背景是“六度空间”。相信听过陈老师的课,都对这道题的背景有所了解。如果没有认真听或者忘记的话,题目是中文的,再读一遍好了。
特别说明:
1. 用邻接表建立图,注意这道题有一个case数据量很大,如果用邻接矩阵肯定会吃不消的。建图时,注意是无向图,所以不管用邻接矩阵还是邻接表,都记得要进行“双向”处理。
2. 需要有一个额外的visited数组,来存储结点是否被访问过。因为要循环遍历所有点,记得当前循环结束时,要将visited数组全部置为false。
3. C++数组是从0开始的,但是为了方便,最好从1开始,申请空间的时候多申请一个就可以了,0那个结点不用管它。这样方便思考和编程。
4. 输出是有严格的格式控制的,我们用到了两个函数setprecision(2)设置小数点精度,setiosflags(ios::fixed)以小数形式输出,需要引入头文件#include <iomanip>,具体请看下面的代码:
/* * 按照相应格式进行输出 */ void Output(int i, double x) { x *= 100; cout << i << ": " << setprecision(2) << setiosflags(ios::fixed) << x << "%" << endl; }
代码分析:
头文件、结构体、所用数据结构的声明及定义:1~26
按照相应格式进行输出:27~35
广度优先遍历:36~75
六度空间问题:76~90
主函数:91~126
1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 #include <iomanip> 5 6 using namespace std; 7 8 /* 9 * 结点结构体的定义,因为没有“权值”问题,因此我们只需要定义一种就可以了! 10 */ 11 template <class T> 12 struct vexNode 13 { 14 T data; 15 vexNode<T> *next; 16 vexNode(T d, vexNode<T> *n = NULL):data(d), next(n) {} 17 }; 18 19 /* 20 * 所用数据结构的含义: 21 * eVec 存储边的信息 22 * visited 存储是否被访问过 23 */ 24 vector<vexNode<int> > eVec; 25 vector<bool> visited; 26 27 /* 28 * 按照相应格式进行输出 29 */ 30 void Output(int i, double x) 31 { 32 x *= 100; 33 cout << i << ": " << setprecision(2) << setiosflags(ios::fixed) << x << "%" << endl; 34 } 35 36 /* 37 * 广度优先遍历 38 */ 39 int BFS ( int V ) 40 { 41 visited[V] = true; 42 int icount = 1; 43 int level = 0; 44 int last = V; 45 int tail; 46 queue<int> Q; 47 Q.push(V); 48 while(Q.size()!=0) 49 { 50 int V = Q.front(); 51 Q.pop(); 52 vexNode<int> *p = &eVec[V]; 53 while( p!= NULL) 54 { 55 int W = p -> data; 56 if ( !visited[W]) 57 { 58 visited[W] = true; 59 Q.push(W); 60 icount++; 61 tail = W; 62 } 63 p = p -> next; 64 } 65 66 if ( V == last ) 67 { 68 level++; 69 last = tail; 70 } 71 if ( level == 6 ) 72 break; 73 } 74 return icount; 75 } 76 77 78 /* 79 * 六度空间问题 80 */ 81 void SDS() 82 { 83 for (int i=1; i<eVec.size(); i++ ) 84 { 85 int icount = BFS(i); 86 Output(i, (double)icount/(eVec.size()-1)); 87 for(int j=0; j<visited.size(); j++) 88 visited[j] = false; 89 } 90 } 91 92 /* 93 * 主函数 94 */ 95 int main() 96 { 97 int nNum, eNum; 98 cin >> nNum >> eNum; 99 for(int i=0; i<nNum + 1; i++) 100 { 101 eVec.push_back(vexNode<int>(i)); 102 visited.push_back(false); 103 } 104 // 用“邻接表”形式存储图 105 for(int i=0; i<eNum; i++) 106 { 107 int a, b; 108 cin >> a >> b; 109 vexNode<int> *p = &eVec[a]; 110 while(p -> next != NULL) 111 { 112 p = p -> next; 113 } 114 p -> next = new vexNode<int>(b); 115 116 vexNode<int> *q = &eVec[b]; 117 while(q -> next != NULL) 118 { 119 q = q -> next; 120 } 121 q -> next = new vexNode<int>(a); 122 } 123 // 调用函数处理问题 124 SDS(); 125 return 0; 126 }
AC成果: