算法导论-第22章-基本的图算法-22.2 广度优先搜索-22.2-4 用邻接矩阵方法实现BFS

来源:互联网 发布:地平线3pc版 优化差 编辑:程序博客网 时间:2024/06/06 09:26

一、题目

如果BFS的输入图是用邻接矩阵表示的,且对该算法加以修改以处理这种输入图表示,那么该算法的运行时间如何?


二、答案与代码

运行时间为O(n^2),处理方法见代码。

1.Mat_Graph.h

#include <iostream>#include<queue>using namespace std;#define N 100#define WHITE 1#define GREY 2#define BLACK 3queue<int> Q;class Mat_Graph{public:int n;int color[N+1];int d[N+1];int Pie[N+1];int Map[N+1][N+1];//邻接矩阵,从1到NMat_Graph(int num):n(num){memset(Map, 0, sizeof(Map));}void AddDoubleEdge(int a, int b, int value = 1){AddSingleEdge(a, b, value);AddSingleEdge(b, a, value);}void AddSingleEdge(int start, int end, int value = 1){Map[start][end] = value;}void DeleteDoubleEdge(int a, int b){DeleteSingleEdge(a, b);DeleteSingleEdge(b, a);}void DeleteSingleEdge(int start, int end){Map[start][end] = 0;}//22.1-2void Print();//22.1-3Mat_Graph* Reverse();//22.1-5Mat_Graph* Square();//22.1-6bool Universal_Sink();void BFS(int s);void Print_Path(int s, int v);};void Mat_Graph::Print(){int i, j;for(i = 1; i <= n; i++){for(j = 1; j <= n; j++)cout<<Map[i][j]<<' ';cout<<endl;}}Mat_Graph* Mat_Graph::Reverse(){int i, j;Mat_Graph *ret = new Mat_Graph(n);for(i = 1; i <= n; i++){for(j = 1; j <= n; j++)if(Map[i][j])ret->AddSingleEdge(j, i);}return ret;}Mat_Graph* Mat_Graph::Square(){int i, j, k;Mat_Graph *ret = new Mat_Graph(n);  //遍历图中每个顶点  for(i = 1; i <= n; i++)  {  for(j = 1; j <= n; j++)  {  if(Map[i][j])  {  //把原来有的边加入到新图中  ret->AddSingleEdge(i, j);//把以E的终点为起点的边加入新图中  for(k = 1; k <= n; k++)  if(Map[j][k])  ret->AddSingleEdge(i, k);  }  }  }  return ret;}//判断某个点是否是通用汇点,即所有点都指向它(除了它自己),但是它不指向任何点bool Mat_Graph::Universal_Sink(){//i指向有可能是汇的编号最小的点  int i = 1, j = 1;  while(j <= n)  {  //map[i][j] = 0,那么j没有i的入,一定不是汇,i可能是汇  if(Map[i][j] == 0)  j++;  //若map[i][j] = 1,则(1)i有出,i不是汇(2)map[i][i+1..j-1]=0,i+1..j-1都不是汇(3)j及j以后的点可能是汇  //若i=j,j也不是汇,j+1可能是汇      else if(i == j)  {  i++;  j++;  }  //若i!=j,j以前的点都不是汇,j可能是汇  else i = j;  }  //没有汇  if(i > n)  return false;  //找到有可能是汇的点,但是还是需要验证一下  else  {  //汇的纵向都是1,除了map[i][i]  for(j = 1; j <= i-1; j++)  {  if(Map[i][j] == 1)  return false;  }  //汇的横向都是0  for(j = 1; j <= n; j++)  if( i != j && Map[j][i] == 0)  return false;  return true;  }  }//广度优先搜索void Mat_Graph::BFS(int s){int u,v;//1、初始化各点的三个属性for(u = 1 ; u <= n ; u++){color[u] = WHITE;d[u] = 0x7fffffff;Pie[u] = 0;}//2、初始化源点s的三个属性color[s] = GREY;d[s] = 0;Pie[s] = 0;//3、清空队列while(!Q.empty())Q.pop();Q.push(s);//4、开始构造优先搜索树while(!Q.empty()){u = Q.front();//把队头出队Q.pop();for(v = 1 ; v <= n ; v++ ){if(Map[u][v] == 0)//v点与u点没有路径continue;if(color[v] == WHITE)//v点与u点之间有路径{color[v] = GREY;d[v] = d[u] + 1;Pie[v] = u;Q.push(v);}}color[u] = BLACK;}}void Mat_Graph::Print_Path(int s, int v){BFS(s);if(s == v){cout<<s<<' ';return;}else{if( Pie[v] == 0 ){cout<<"No path from "<<s<<" to "<<v<<endl;return;}else{Print_Path(s,Pie[v]);cout<<v<<' ';}}}

2.main.cpp

#include <iostream>//#include "Link_Graph.h"#include "Mat_Graph.h" using namespace std;/*边1 21 52 66 76 33 73 47 87 44 8*//*有向图1→2→6 → 3↓    ↓↙ ↓5     7 → 4      ↓ ↙       8 */int main(){int graph[9][2]={{0,0},{1,2},{1,4},{2,5},{3,5},{3,6},{4,2},{5,4},{6,6}};Mat_Graph *G = new Mat_Graph(6);int i = 0, a, b;for(i = 1; i <= 8; i++){//cin>>a>>b;a=graph[i][0];b=graph[i][1];G->AddSingleEdge(a,b);//有向图//G->AddDoubleEdge(a,b);//无向图}G->BFS(3);//对点3进行广度优先搜索,并构造广度优先搜索树for(i = 1; i <= 6; i++){cout<<G->d[i]<<' ';//输出各个点到点3的距离,对于有向图,对于没有到点3的路径的点,则对应的距离为0x7fffffff}cout<<endl;int s, v;//求点s,v之间的路径while(cin>>s>>v){G->Print_Path(s, v);cout<<endl;}return 0;}

转自:http://blog.csdn.net/mishifangxiangdefeng/article/details/7837922
0 0
原创粉丝点击