题目 A3:有向图的简单路径求解问题
给定一个有向图 G 两个顶点 a和 b,试编写算法求a到b的简单路径的数量,并分别输出最短的简单路径和最长的简单路径
#define PATH_HEADER_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define ERROR 0
#define OK 1
#define Overflow 2 //Overflow表示上溢出
#define Underflow 3 //Underflow表示下溢出
#define NotPresent 4 //NotPresent表示元素不存在
#define Duplicate 5 //Duplicate 表示有重复的元素
#define STLEN 5
static int sum = 0; //统计有几条简单路径
static int min_number = 100; //假设此图最多包含100个顶点
typedef int Status;
typedef int ElemType;
typedef struct eNode
{
int adjVex; //与任意顶点u相邻接的顶点
ElemType w; //边的权值
struct eNode* nextArc; //指向下一个边节点
}ENode;
typedef struct lGraph
{
int n; //图的当前顶点数
int e; //图的当前边数
ENode **a; //指向一维指针数组
}LGraph;
Status Init(LGraph *lg, int nSize);
void Destroy(LGraph *lg);
Status Exist(LGraph *lg, int u, int v);
Status Insert(LGraph *lg, int u, int v,ElemType w);
Status Remove(LGraph *lg, int u, int v);
void DFS(int v, int length, int visited[],LGraph *Lg);
void DFSGraph(LGraph *Lg);
int min = INT_MAX;
int max = INT_MIN;
void Destroy(LGraph *lg)
{
ENode *p, *q;
for (int i = 0; i < lg->n; i++)
{
p = lg->a[i];
q = p;
while (p)
{
p = p->nextArc;
free(q);
q = p;
}
}
free(lg->a);
}
Status Exist(LGraph *lg, int u, int v)
{
ENode *p;
if (u < 0 || v < 0 || u > lg->n - 1 || v > lg->n - 1 || u == v)
{
return ERROR;
}
p = lg->a[u];
while (p && p->adjVex != v)
{
p = p->nextArc;
}
if (!p)
{
return ERROR;
}
else
{
return OK;
}
}
Status Insert(LGraph *lg, int u, int v, ElemType w)
{
ENode *p;
if (u < 0 || v < 0 || u > lg->n - 1 || v > lg->n - 1 || u == v)
{
return ERROR;
}
if (Exist(lg, u, v))
{
return Duplicate;
}
p = (ENode *)malloc(sizeof(ENode *)); //为新的节点分配内存
p->adjVex = v;
p->w = w;
p->nextArc = lg->a[u]; //将新的边节点插入单链表的最前面
lg->a[u] = p;
lg->e++;
return OK;
}
Status Remove(LGraph *lg, int u, int v)
{
ENode *p, *q;
if (u < 0 || v < 0 || u > lg->n - 1 || v > lg->n - 1 || u == v)
{
return ERROR;
}
p = lg->a[u], q = NULL;
while (p && p->adjVex != v)
{
q = p;
p = p->nextArc;
}
if (!p)
{
return NotPresent; //p为空,待删除边不存在
}
if (q)
{
q->nextArc = p->nextArc; //从单链表删除此边
}
else
{
lg->a[u] = p->nextArc; //此时为第一个边节点就是待删除边的情况
}
free(p);
lg->e--;
return OK;
}
void DFS(int v, int length, int visited[], int path[], LGraph *Lg, int* count) {
for (p = Lg->a[v]; p; p = p->nextArc) {
if (!visited[p->adjVex] && p) {
visited[p->adjVex] = 1;
path[length + 1] = p->adjVex; // 将经过的顶点添加到路径中
DFS(p->adjVex, length + 1, visited, path, Lg, count);
visited[p->adjVex] = 0;
}
}
}
int main()
{
LGraph Lg; //声明一个图,名字为Lg
int n; //此图顶点的个数
printf("请输入需要此图需要的顶点数:");
scanf("%d",&n);
getchar();
int status = Init(&Lg, n); //初始化图,为每个顶点分配内存空间,初始化成功,status为1,反之返回0
if(!status)
{
printf("没有成功动态生成长度为%d的一维指针数组,程序终止运行!\n\n",n);
}
else
{
printf("带有%d个顶点的图已经初始化完成,请插入边<u,v>及权值w,以构成完整的图\n\n",n);
}
int u, v, w; //表示顶点u、v和权值w
int i = 1; //统计第几条边
char flag[5];//接收输入
printf("是否准备为初始化的图插入边(yes/no):");
gets(flag);
while(strcmp(flag, "yes") == 0)
{
printf("请插入第%d条边<u,v>及权值w:",i);
scanf("%d %d %d",&u,&v,&w);
getchar();
status = Insert(&Lg, u, v, w); //检查插入操作是否成功
if(status == 5)
{
printf("您输入的顶点已存在,请重新输入!\n\n");
continue;
}
else if(status == 0)
{
printf("参数u=%d、v=%d无效,请重新输入!\n\n",u, v);
continue;
}
else
{
printf("第%d条边已经成功插入完成!\n\n",i);
}
i++; //为即将插入的边做好准备
printf("是否继续插入边(yes/no):");
gets(flag); //接收输入
if(strcmp(flag, "yes") != 0)
{
printf("带有%d个顶点的图一共成功插入%d条边\n\n",n, i-1);
break;
}
}
int m = i-1; //为了统计还剩下几条边
printf("是否错误插入某条边,请删除!(yes/no):");
gets(flag);
i = 1;
while(strcmp(flag, "yes") == 0)
{
printf("请输入要删除第%d条边<u,v>:",i);
scanf("%d %d",&u,&v);
getchar();
status = Remove(&Lg, u, v); //调用remove操作,返回删除操作的状态
if(status == 4)
{
printf("您输入的顶点不存在,请重新输入!\n\n");
continue;
}
else if(status == 0)
{
printf("参数u=%d、v=%d无效,请重新输入!\n\n",u, v);
continue;
}
else
{
printf("第%d条边已经成功删除完成!\n\n",i);
}
i++;//为继续删除边做好准备
printf("是否继续删除边(yes/no):");
gets(flag);
if(strcmp(flag, "yes") != 0)
{
printf("带有%d个顶点的图一共删除了%d条边,还剩下%d条边\n\n",n, i-1, m-(i-1));
break;
}
}
Destroy(&Lg); //释放内存空间
return 0;
}
代码不完整,欢迎交流 需要完整代码联系我:维新:lxt123lxp456