中国大学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成果:

posted @ 2015-01-03 12:25  聪明的聪聪  阅读(722)  评论(0编辑  收藏  举报