一个连通图采用邻接表作为存储结构。设计一个算法,判断无向图中任意给定的两点是否存在一条长度为k的简单路径。
#include<iostream>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MVNum 100 //最大顶点数
using namespace std;
typedef struct ArcNode
{//边结点
int adjvex; //邻接点域:该边所指向的顶点的位置
char data; //数据域:存储和边相关的信息
struct ArcNode* nextarc; //链域:指向下一条边的指针
}ArcNode;
typedef struct VNode
{//顶点信息
char data; //顶点结点的数据域
ArcNode *firstarc; //链域:指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum]; //AdjList表示邻接表类型
typedef struct
{//邻接表
AdjList vertices;
int vexnum,arcnum; //图的当前顶点数和边数
}ALGragh;
int Locate(char ch[],char h)
{//存在则返回h在数组中的下标,否则返回ERROR
int i;
for(i=0;ch[i]!='\0';i++)
{
if(ch[i]==h)
return i;
}
return ERROR;
}
bool visited[MVNum]; //访问标记数组,已访问顶点的值记为true
bool PathLenK(ALGragh G,int pD,int pF,int k)
{//判断邻接表方式存储的有向图G的顶点pD到pF是否存在长度为k的简单路径
if(pD==pF&&k==0) return true; //找到了一条路径,且长度符合要求
else if(k>0) //从结点pD开始遍历,p为pD的边链表的第一个结点
{
visited[pD]=true;
ArcNode *p;
for(p=G.vertices[pD].firstarc;p;p=p->nextarc)
{
int v=p->adjvex;
if(!visited[v]) //v从未被访问过
{
if(PathLenK(G,v,pF,k-1))
return true; //递归继续遍历判断pD到pF,且剩余路径长度减1
}
}
visited[pD]=false;//允许曾经被访问过的结点出现在另一条路径中
}
return false; //没找到
}
int CreateUDG(ALGragh &G,int vexnum,int arcnum,char ch[])
{//采用邻接表表示法,创建无向图G
/**************begin************/
/**************end************/
}
int main()
{
int n,m,k; //n个顶点,m条边和长度k
while(cin>>n>>m>>k)
{
if(n==0&&m==0&&k==0) break;
char ch[MVNum];
cin>>ch;
ALGragh G;
CreateUDG(G,n,m,ch); //创建无向图G
char d,f; //d和f代表需要判断的两个字符
cin>>d>>f;
int pd=Locate(ch,d);
int pf=Locate(ch,f);
if(PathLenK(G,pd,pf,k))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}