只有两点要求:
1)求出无向图中从起点到终点的所有简单路径。其中起点和终点可以由用户自行设定。
2)求出无向图中从起点到终点的指定长度(如K)的所有简单路径。其中起点和终点可以由用户自行设定。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXV 100 //最大顶点个数
int visited[MAXV];
//邻接矩阵类型
typedef struct
{
int no; //顶点号
int info; //边的权值
}Vertextype; //顶点类型
typedef struct
{
int edges[MAXV][MAXV];//邻接矩阵
int n,e; //顶点数,弧数
Vertextype vexs[MAXV];//顶点信息
}Mgraph;
//邻接表信息
typedef struct Anode //弧结点
{
int adjvex; //终点
struct Anode *next;//下一条弧
int info;//弧权值
}ArcNode;
typedef struct Vnode
{
int data; //邻接表的头结点
ArcNode * first;//第一条弧
}Vnode;
typedef struct
{
Vnode adjlist[MAXV];//邻接表
int n,e;//定点数,弧数
}AlGraph;
void Change(Mgraph g,AlGraph *&G)//将邻接矩阵转换为邻接表
{
int i,j,n =g.n;
ArcNode *p;
G= (AlGraph *)malloc(sizeof(AlGraph));
for(i=0;i<n;i++) //初始化
{
G->adjlist[i].first = NULL;
}
for(i=0;i<n;i++)
for(j=n-1;j>=0;j--) //依次遍历邻接矩阵存到响应的邻接表
{
if(g.edges[i][j]!=0)
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;//弧的后一个点
p->info = g.edges[i][j];//权值
p->next = G->adjlist[i].first;
G->adjlist[i].first = p;//接到每一行头结点的后面
}
}
G->n = n;//顶点数
G->e =g.e;//弧数
}
void DisADJ(AlGraph *G)//输出邻接表
{
int i;
ArcNode *p;
printf("************邻接表如下*************\n");
for(i = 0;i<G->n;i++)
{
p=G->adjlist[i].first;//从每一行的头结点向后面遍历
if(p!=NULL)printf("%d: ",i);
while(p!=NULL)
{
printf("%3d",p->adjvex);
p=p->next;
}
printf("\n");
}
}
void showways1(AlGraph *G,int x,int y,int path[],int i)//利用邻接表求
{
ArcNode *p;
int j,n;
visited[x] = 1;//记录已经用过这个顶点
p=G->adjlist[x].first;
while(p!=NULL)
{
n=p->adjvex;
if(n==y) //找到一个路径
{
path[i+1] = y;
for(j=0;j<=i+1;j++)
printf(" %3d",path[j]);
printf("\n");
}
else if(visited[n]==0) //该点未被遍历
{
path[i+1] = n;//存入路径
showways1(G,n,y,path,i+1); //递归
}
p=p->next;
}
visited[x] =0;
}
void showways2(Mgraph g,int x,int y,int path[],int i)//利用邻接矩阵求
{
visited[x]=1;//标记该点
int j;
path[i] = x;//存入路径
for(j = 0;j<g.n;j++)//遍历邻接点
{
if(g.edges[x][j]!=0)
{
if(j==y)//满足到顶点v
{
path[i+1]=j;
int k;
for(k=0;k<=i+1;k++)//输出一组路径
printf(" %3d",path[k]);
printf("\n");
}
else if(j!=y&&visited[j]==0){
showways2(g,j,y,path,i+1);
}
}
}
visited[x]=0;//取消标记
}
void showways3(AlGraph *G,int x,int y,int l,int path[],int d) //输出满足制定长度路径
{
int m,i;
ArcNode *p;
visited[x] =1;
d++;
path[d] = x;
if(x==y&&d==l)//找到一个路径
{
for(i = 0;i<=d;i++)
printf(" %3d",path[i]);
printf("\n");
}
p = G->adjlist[x].first;
while(p!=NULL) //递归循环查找
{
m = p->adjvex;
if(visited[m]==0)//未遍历的点
showways3(G,m,y,l,path,d);
p=p->next;
}
visited[x] = 0;
}
void showways4(Mgraph g,int x,int y,int l,int path[],int d)
{
visited[x]=1;
int j;
d++;
path[d] = x;
for(j = 0;j<g.n;j++)
{
if(g.edges[x][j]!=0)
{
if(j==y&&d==l-1)//找到一组路径
{
path[d+1]=j;
int k;
for(k=0;k<=d+1;k++)
printf(" %3d",path[k]);
printf("\n");
}
else if(j!=y&&visited[j]==0){//未找到 继续遍历
showways4(g,j,y,l,path,d);
}
}
}
visited[x]=0;
}
int main()
{
int A[MAXV][20];
int i,j;
Mgraph g;//邻接矩阵
AlGraph *G;//邻接表
printf("*****请选择 1 默认无向图, 2 输入无向图********** \n\n");
int h;
scanf("%d",&h);
switch(h){
case(1):
{
g.n = 11;
g.e = 13;
for(i = 0;i<g.n;i++)//创建邻接矩阵
for(j =0;j<g.n;j++)
A[i][j] = 0;
A[0][3]=A[0][2]=A[0][1]=A[1][5]=A[1][4]=A[2][6]=A[2][5]=A[2][3]=A[3][7]=A[6][9]=A[6][8]=A[6][7]=A[7][10]=1;
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++){
A[j][i] = A[i][j];
g.edges[i][j] = A[i][j];
}
break;
}
case(2):
{
int q,p;
printf("\n********请输入顶点数,一半路径数**********\n\n");
scanf("%d%d",&g.n,&g.e);
printf("\n***********请按照邻接矩阵形式输入无向图*******\n\n");
for(i=0;i<g.n;i++)
for(j=0;j<g.n;j++){
cin>>g.edges[i][j];
}
break;
}
}
G =(AlGraph *)malloc(sizeof(AlGraph));
Change(g,G); //转换成邻接表
DisADJ(G);//输出邻接表
printf("****************选择***********************\n\n");
int k,u,v,m;
int path[MAXV];
printf("1.代表求出无向图中从起点到终点的所有简单路径\n\n");
printf("2.代表无向图中从起点到终点的指定长度的所有简单路径\n\n");
printf("**********************************************\n");
while(true){
for(i=0;i<g.n;i++)
visited[i]=0;
printf("请输入选择 1模式 或 2模式。\n\nk = ");
scanf("%d",&k);
switch(k){
case(1):
{
printf("请输入两个点属于1-10.\n\n");
scanf("%d%d",&u,&v);
path[0]=u;
visited[u] = 1;
printf("\n路径如下:(无则代表输入路径不存在)\n\n");
printf("*****************************************\n\n");
printf("用邻接表求得如下:\n\n");
showways1(G,u,v,path,0);
printf("*****************************************\n\n");
printf("用邻接矩阵求得如下:\n\n");
for(i=0;i<g.n;i++)
visited[i]=0;
showways2(g,u,v,path,0);
printf("*****************************************\n\n");
break;
}
case(2):
{
printf("请输入两个点(1-10)及制定长度(1-9) (无则代表输入无效)\n\n");
scanf("%d%d%d",&u,&v,&m);
path[0]=u;
visited[u] = 1;
printf("\n路径如下:\n\n");
printf("*****************************************\n\n");
printf("用邻接表求得如下:\n\n");
showways3(G,u,v,m,path,-1);
printf("*****************************************\n\n");
printf("用邻接矩阵求得如下:\n\n");
for(i=0;i<g.n;i++)
visited[i]=0;
showways4(g,u,v,m,path,-1);
printf("*****************************************\n\n");
break;
}
default: printf("没有这个选项 请重新输入。 \n");
printf("*****************************************\n\n");
}
}
return 0;
}