[PTA] Week 11 4-16 Shortest Path [3] (25分)

#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 path[], Vertex S );

int main()
{
	freopen("test.txt","r",stdin);
    int dist[MaxVertexNum], path[MaxVertexNum];
    Vertex S, V;
    MGraph G = ReadG();

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

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

    return 0;
}

MGraph ReadG()
{
	int i,j;
	int w,v,x;
	MGraph p;
	p=(PtrToGNode)malloc(sizeof(struct GNode));
	scanf("%d%d",&w,&v);
    p->Nv=w,p->Ne=v; 
	for(i=0;i<p->Nv;i++){
		for(j=0;j<p->Nv;j++){
			p->G[i][j]=-1;
		}
	}
	for(i=0;i<p->Ne;i++){
		scanf("%d%d%d",&w,&v,&x);
		p->G[w][v]=x;
	}
	return p;
}

void ShortestDist( MGraph Graph, int dist[], int count[], Vertex S )
{
	bool visit[MaxVertexNum];
	int dist2[MaxVertexNum];
	int i; 
	
	/*初始化 */
	for(i=0;i<Graph->Nv;i++){
		dist[i]=INFINITY; /*dist[i]代表从S到i的最短距离 */
		dist2[i]=INFINITY;
		count[i]=0; /* count[i]代表从S到i的最短路径条数 */
		visit[i]=false; /* 是否访问过该结点 */
	}
	
	for(i=0;i<Graph->Nv;i++){
		if(Graph->G[S][i]>0){
			dist[i]=Graph->G[S][i]; 
		}
	}
	
	visit[S]=true;
	dist[S]=0;
	
	/*第一次dijikstra,计算最短路径*/ 
	
	while(1){
		int min=INFINITY;
		int v=-1;
		/*得到最小的dist,将v点加入结果,求得从S到v的最短路径dist[v]*/ 
		for(i=0;i<Graph->Nv;i++){
			if(!visit[i]){
				if(dist[i]<min){
					min=dist[i];
					v=i;
				}
			}
		}
		/*找不到最小的dist,跳出循环*/ 
		if(v==-1)break;
		visit[v]=true;
		/*扫描v的所有邻接点,如果经过v到其邻接点的距离比已有距离更短,更新最短距离*/ 
		for(i=0;i<Graph->Nv;i++){
			if(!visit[i]&&Graph->G[v][i]>0){
				if(dist[v]+Graph->G[v][i]<dist[i]){
					dist[i]=dist[v]+Graph->G[v][i];
				}	
			}
		}	
	}
	
	
	/*初始化*/ 
	
	for(i=0;i<Graph->Nv;i++){
		if(dist[i]==INFINITY)dist[i]=-1;
		visit[i]=false;
	} 
	
	visit[S]=true;
	count[S]=1;
	dist2[S]=0;
	
	for(i=0;i<Graph->Nv;i++){
		if(Graph->G[S][i]>0){
			dist2[i]=Graph->G[S][i];
			if(dist2[i]==dist[i]){
				count[i]=1;  /*如果S到i的直接路径为最短路径,更新最短路径条数 */ 
			}
		}
	}
	
	/*第二次dijikstra,计算最短路径条数*/ 
	
	while(1){
		int v=-1;
		int min=INFINITY;
		for(i=0;i<Graph->Nv;i++){
        	if(!visit[i]&&dist2[i]<min){
                 min=dist2[i];
				 v=i;
             }
        }
        if(v==-1)break;
        visit[v]=true;
        for(i=0;i<Graph->Nv;i++){
            if(!visit[i]&&Graph->G[v][i]>0){
            	if(dist2[v]+Graph->G[v][i]<dist2[i]){
					dist2[i]=dist2[v]+Graph->G[v][i];	
					count[i]=count[v];
					/* 如果经过v到达i的路径为第一条最短路径,
					   那么从S到i的最短路径条数等于从S到v的最短路径条数*/ 
				}
				else if(dist2[v]+Graph->G[v][i]==dist[i])
                	count[i]+=count[v];
					/* 如果经过v到达i的路径为新的最短路径,
					   那么从S到i的最短路径条数等于从S到i的最短路径条数
					   加上从S到v的最短路径条数*/ 
             }
         }
     }
} 

你可能感兴趣的:([PTA] Week 11 4-16 Shortest Path [3] (25分))