返回目录:
Chilan Yu:《数据结构》目录链接zhuanlan.zhihu.com1. 图中两个顶点之间的简单路径
简单路径:若表示路径的顶点序列中的顶点各不相同,则称这样的路径为简单路径。
顶点u到v可能存在多条简单路径,可以在DFS和BFS基础上加上适当条件求解。
【算法思想】
从顶点u开始,进行深度(或广度)优先搜索,如果能够搜索到顶点v,则表明从顶点u到顶点v有一条路径。由于在搜索过程中,每个顶点只能访问一次,所以这条路径必定是简单路径。因此,只要在搜索的过程中,把搜索的路径记录下来,并在搜索到顶点
时退出搜索过程,就可以得到从u到v一条简单路径。
为了记录搜索线路,需要设置一个数组pre[n],当从某个顶点
找到其邻接顶点
进行访问时,将pre[j]置为i。这样,当退出搜索后,就能根据pre数组从顶点v追溯到顶点u,从而输出这条从u到v的简单路径。
具体设计这一算法时,可以顺便使用pre数组代替visited数组,用pre[j]=-1表示
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define MAX_VERTEX_NUM 20//最多顶点个数
#define INFINITY 32768//表示极大值
int pre[MAX_VERTEX_NUM];//访问标志数组兼路径数组
typedef struct Graph{
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//二维数组存储邻接矩阵
int vexnum;//顶点数
}Graph;
/*矩阵建图/网*/
//图:0表示没有边,1表示有边
//网:0表示没有边,非0表示边上权值
void CreateMatrix(Graph * G){//一般从下标0开始存图
cout << "请输入顶点数:";
cin >> G->vexnum;
cout << "请输入矩阵:" << endl;
for(int i=0;i<G->vexnum;++i)
for(int j=0;j<G->vexnum;++j)
cin >> G->arcs[i][j];
}
/*打印简单路径*/
void print_path(int v){
int u;//起始点下标
int num = 0;
int path[MAX_VERTEX_NUM];//倒序路径下标
path[0] = v;
for(u=pre[v];u!=-2;u=pre[u]){//找到起始点下标
num++;
path[num] = u;
}
for(;num>=0;--num)
cout << path[num]+1 << " ";//注意顶点从1开始,数组从0开始存储
cout << endl;
}
/*邻接矩阵DFS遍历v所在的连通子图*/
void DFS(Graph * G,int u,int v){
for(int w=0;w<G->vexnum;++w){//寻找下一个联通顶点
if(pre[w]==-1 && G->arcs[u][w]==1){//既要相连又要没有访问过
pre[w] = u;//记录其前驱结点下标
if(w==v) print_path(v);
else DFS(G,w,v);
}
}
}
/*DFS找顶点u到顶点v简单路径*/
void DFS_path(Graph * G,int u,int v){
for(int i=0;i<G->vexnum;++i)
pre[i] = -1;//初始化pre数组
pre[u] = -2;//起始点特殊处理,表示已经访问而且没有前驱
DFS(G,u,v);
}
int main()
{
Graph G;
CreateMatrix(&G);
int u,v;
cout << "请输入顶点u和v:";
cin >> u >> v;
DFS_path(&G,u-1,v-1);//注意数组下标从0开始
return 0;
}