题目 A3:有向图的简单路径求解问题给定一个有向图 G 两个顶点 a和 b,试编写算法求a到b的简单路径的数量,并分别输出最短的简单路径和最长的简单路径

题目 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

猜你喜欢

转载自blog.csdn.net/qq_62088638/article/details/134522075