最短路径问题(1)

    作为一名小白,最近学习了Dijkstra算法,对于最短路径的解有了一定的认识,从PTA的题目来说明Dijkstra算法

4-1 Shortest Path [3]   (25分)

Write a program to not only find the weighted shortest distances, but also count the number of different minimum paths from any vertex to a given source vertex in a digraph. It is guaranteed that all the weights are positive.

Format of functions:

void ShortestDist( MGraph Graph, int dist[], int count[], Vertex S );

where MGraph is defined as the following:

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;
    int Ne;
    WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;

The shortest distance from V to the source S is supposed to be stored in dist[V]. If V cannot be reached from S, store -1 instead. The number of different minimum paths from V to the source S is supposed to be stored in count[V] and count[S]=1.

Sample program of judge:

#include <stdio.h>
#include <stdlib.h>

typedef enum {false, true} bool;
#define INFINITY 1000000
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */
typedef int WeightType;

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;
    int Ne;
    WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;

MGraph ReadG(); /* details omitted */

void ShortestDist( MGraph Graph, int dist[], int count[], Vertex S );

int main()
{
    int dist[MaxVertexNum], count[MaxVertexNum];
    Vertex S, V;
    MGraph G = ReadG();

    scanf("%d", &S);
    ShortestDist( G, dist, count, S );

    for ( V=0; V<G->Nv; V++ )
        printf("%d ", dist[V]);
    printf("\n");
    for ( V=0; V<G->Nv; V++ )
        printf("%d ", count[V]);
    printf("\n");

    return 0;
}

/* Your function will be put here */

Sample Input (for the graph shown in the figure):

8 11
0 4 5
0 7 10
1 7 30
3 0 40
3 1 20
3 2 100
3 7 70
4 7 5
6 2 1
7 5 3
7 2 50
3

Sample Output:

40 20 100 0 45 53 -1 50 
1 1 4 1 1 3 0 3
void ShortestDist( MGraph Graph, int dist[], int count[], Vertex S )
{
	int v, min;
	int visit[MaxVertexNum];           /*判断是否经过*/ 
	int dist1[MaxVertexNum];
	for(int i=0; i<Graph->Nv; i++)     /*初始化*/ 
	{
		dist[i]=Graph->G[S][i];
		count[i]=0;
		visit[i]=0;
	}
	dist[S]=0;
	count[S]=1;
	visit[S]=1;
	for(int i=0; i<Graph->Nv-1; i++)
	{
		min=INFINITY;
		for(int j=0; j<Graph->Nv; j++)
		{
			if(visit[j]==0&&dist[j]<min)     /*找到未遍历且距离源点最短的点*/ 
			{
				v=j;
				min=dist[j];
			}
		}
		if(min==INFINITY)
		break;
		visit[v]=1;
		for(int j=0; j<Graph->Nv; j++)
		{
			if(dist[j]>dist[v]+Graph->G[v][j])  /*更新各点距离源点的最短路径*/ 
			{
				dist[j]=dist[v]+Graph->G[v][j];
			}
		}
	}
	for(int i=0; i<Graph->Nv; i++)
	{
		if(dist[i]==INFINITY)
		{
			dist[i]=-1;
			count[i]=0;
		}
	}
	/*寻找最短路径条数*/ 
	for(int i=0; i<Graph->Nv; i++)
	{
		visit[i]=0;
		dist1[i]=Graph->G[S][i];
		if(dist[i]==dist1[i])
		count[i]=1;
	} 
	dist1[S]=0;
	count[S]=1;
	visit[S]=1;
    for(int i=0; i<Graph->Nv-1; i++)
    {
    	min=INFINITY;
    	for(int j=0; j<Graph->Nv; j++)
    	{
    		if(visit[j]==0&&dist1[j]<min)
    		{
    			v=j;
    			min=dist1[j];
			}
		}
		if(min==INFINITY)
		break;
		visit[v]=1;
		for(int j=0; j<Graph->Nv; j++)
		{
			if(dist1[v]+Graph->G[v][j]==dist1[j])     /*找到等长的最短路径则在原有基础上增加*/ 
			count[j]=count[j]+count[v];
			else if(dist1[v]+Graph->G[v][j]<dist1[j]) /*如果有更小的路径则更新最小路径条数*/ 
			{
			    count[j]=count[v];
			    dist1[j]=dist1[v]+Graph->G[v][j];
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值