2021/05/28 无权图的单源最短路径

如上有向无权图:总共7个顶点12条边

如果以顶点3开始,那么它对应的去每个顶点的路径应该是:

 

顶点1   3->11
顶点2   3->1->22
顶点3   3->30
顶点4   3->1->4 2
顶点5   3->1->2->53
顶点6   6->31
顶点7   3->1->4->73

这里用到的算法与BFS类似;还是需要一个队列(出队入队操作)

typedef struct node{
	int date[MAX];
	int tail;
	int head;
}Quque;
void add(int x,Quque *Q)//入队
{		
	Q->date[Q->tail++]=x;	
}
int isEmpty(Quque *Q)  //是否非空?
{
	if(Q->head>=Q->tail)
	return 1;
	else
	return 0;
}
int delet(Quque *Q)//出队
{
	int x=Q->date[Q->head];
	Q->head++;
	return x;
}

然后需要两个数组,不同于BFS(visit数组),这里用了一个dist[] (记录路径长度,初始化-1)和一个path[](记录来时走过的路)

int dist[110];
int path[110];
for(i=0;i<110;i++)//初始化为-1
dist[i]=-1;
for(i=0;i<110;i++)//初始化为-1
path[i]=-1;

当要寻找最短路径的源头为i时,dist[i]=0;(自己到自己长度为0) 

void unweighted(int i,Quque *Q)
{	
	add(i,Q);//将顶点i入队 			
	while(!isEmpty(Q)) //当队列非空
    {
		int j,t=delet(Q);//令t=出队
		 for(j=1;j<=N;j++)//遍历所有顶点
        {
		  if(a[t][j]==1&&dist[j]==-1)//如果出队的顶点t还有其他边 并且没访问过(路径等于-1) 
		 {					
			dist[j]=dist[t]+1;//路径+1 
			path[j]=t;  //记录上一个路径 
			add(j,Q);//将该顶点入队
		 }
	    }			
	}
}

完整代码测试:

//无权图单源最短路径 
#include<stdio.h>
#include<stdlib.h>
#define MAX 110
int N;
int E;
int a[10][10];
int dist[110];
int path[110];
int way[110];
typedef struct node{
	int date[MAX];
	int tail;
	int head;
}Quque;
void add(int x,Quque *Q);
int isEmpty(Quque *Q);
int delet(Quque *Q);
void unweighted(int i,Quque *Q);
int main()
{
	int i,x1,x2;
	for(i=0;i<110;i++)
	dist[i]=-1;
	for(i=0;i<110;i++)
	path[i]=-1;
	scanf("%d%d",&N,&E);
	for(i=0;i<E;i++)
	{
		scanf("%d%d",&x1,&x2);
		a[x1][x2]=1;
	}	
	Quque *Q=(Quque*)malloc(sizeof(Quque));
	Q->head=Q->tail=0;
	dist[3]=0;//顶点设为3 初始化为0	
	unweighted(3,Q);
	for(i=1;i<=N;i++)
    {
     	printf("顶点3到顶点%d的路径长度:%d\n",i,dist[i]);  //输出每个顶点到3的最短路径 
     	int t=i;
     	int cnt=0;
     	way[cnt]=3;
     	printf("路径%d",way[cnt]);
	    while(path[t]!=-1)
	    {
	    	way[cnt++]=t;
	    	t=path[t];
		}
		while(cnt--)	printf("->%d",way[cnt]);					
		printf("\n");
    }
	return 0;
}
void add(int x,Quque *Q)
{		
	Q->date[Q->tail++]=x;	
}
int isEmpty(Quque *Q)
{
	if(Q->head>=Q->tail)
	return 1;
	else
	return 0;
}
int delet(Quque *Q)
{
	int x=Q->date[Q->head];
	Q->head++;
	return x;
}
void unweighted(int i,Quque *Q)
{	
	add(i,Q);//将顶点i入队 			
	while(!isEmpty(Q)) //当队列非空
    {
		int j,t=delet(Q);//令t=出队
		 for(j=1;j<=N;j++)//遍历所有顶点
        {
		  if(a[t][j]==1&&dist[j]==-1)//如果出队的顶点t还有其他边 并且没访问过(路径等于-1) 
		 {					
			dist[j]=dist[t]+1;//路径+1 
			path[j]=t;  //记录上一个路径 
			add(j,Q);//将该顶点入队
		 }
	    }			
	}
}

 最后输出:

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值