[PTA] Shortest Path [3]

#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的最短路径条数*/ 
             }
         }
     }
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值