进阶实验6-3.3 天梯地图 (30分)-Dijkstra

解题思路:采用Dijkstra算法,算两次,一次算最短时间,一次算最短路径,另开一数组记录路径

#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
#define MaxVex 500
typedef struct {
    int length;
    int time;
} Graph;
Graph G[MaxVex][MaxVex];//图
int visit[MaxVex]= {0};//访问标记
int fpath[MaxVex];//最快路径
int lpath[MaxVex];//最短路径
int num[MaxVex]={0};//节点计数
int Nv,Ne;
//图初始化-邻接矩阵
void Init() {
    int i,j;
    for(i=0; i<Nv; i++) {
        for(j=0; j<Nv; j++) {
            G[i][j].length=INF;
            G[i][j].time=INF;
        }

    }
    int v1,v2,one_way,length,time;
    for(i=0; i<Ne; i++) {
        scanf("%d %d %d %d %d",&v1,&v2,&one_way,&length,&time);
        G[v1][v2].length=length;
        G[v1][v2].time=time;
        if(!one_way) {
            G[v2][v1]=G[v1][v2];
        }
    }
}
void Dijkstra(int s,int type) {
    visit[s]=1;
    num[s]=1;
    int i,j,w,MIN;
    //计算最快路径,如果最快路径不唯一,则选最短路径
    if(type==1) {
        for(i=0; i<Nv; i++) {
            MIN=INF;
            for(j=0; j<Nv; j++) {
                if(!visit[j]&&G[s][j].time<MIN) {
                    MIN=G[s][j].time;
                    w=j;
                }
            }
            visit[w]=1;
            for(j=0; j<Nv; j++) {
                if(!visit[j]&&MIN+G[w][j].time<G[s][j].time) {
                    G[s][j].time=MIN+G[w][j].time;
                    fpath[j]=w;
                } else if(!visit[j]&&MIN+G[w][j].time==G[s][j].time) {
                    //注意这里的最短路径是 G[w][j].length<G[fpath[j]][j].length
                    //而不是G[s][w].length+G[w][j].length<G[s][j].length
                    if(G[w][j].length<G[fpath[j]][j].length) {
                        fpath[j]=w;
                    }
                }
            }
        }
    } else if(type==2) {//计算最短路径,如果不唯一,则先节点少的
        for(j=0; j<Nv; j++) {
            MIN=INF;
            for(i=0; i<Nv; i++) {
                if(!visit[i]&&G[s][i].length<MIN) {
                    MIN=G[s][i].length;
                    w=i;
                }
            }
            visit[w]=1;
            for(i=0; i<Nv; i++) {
                if(!visit[i]&&MIN+G[w][i].length<G[s][i].length) {
                    G[s][i].length=MIN+G[w][i].length;
                    lpath[i]=w;
                    num[i]=num[w]+1;
                } else if(!visit[i]&&MIN+G[w][i].length==G[s][i].length) {
                    if(num[w]+1<num[i])
                    {
                        num[i]=num[w]+1;
                        lpath[i]=w;

                    }

                }
            }
        }
    }
}
//判断两条路径是不否一样
int IsTheSame(int a[],int n,int b[],int m) {
    if(n!=m)
        return 0;
    else {
        int i;
        for(i=0; i<=n; i++) {
            if(a[i]!=b[i])
                return 0;
        }
        return 1;
    }

}
int main() {
    scanf("%d %d",&Nv,&Ne);
    Init();
    int s,d,i;
    scanf("%d %d",&s,&d);
    memset(visit,0,sizeof(visit));
    for(i=0; i<Nv; i++) {
        fpath[i]=s;
    }
    Dijkstra(s,1);

    memset(visit,0,sizeof(visit));
    for(i=0; i<Nv; i++) {
        lpath[i]=s;
    }
    Dijkstra(s,2);
    //逆向输出路径存入数组
    int f=d,l=d;
    int FRoad[MaxVex]= {0},LRoad[MaxVex]= {0};
    int t=0,k=0;
    while(f!=s) {
        FRoad[t++]=f;
        f=fpath[f];
    }
    FRoad[t]=s;
    while(l!=s) {
        LRoad[k++]=l;
        l=lpath[l];
    }
    LRoad[k]=s;
    //结果输出
    if(IsTheSame(FRoad,t,LRoad,k)) {
        printf("Time = %d; Distance = %d: ",G[s][d].time,G[s][d].length);
        for(i=t; i>=0; i--) {
            printf("%d",FRoad[i]);
            if(i)
                printf(" => ");
        }
    } else {
        printf("Time = %d: ",G[s][d].time);
        for(i=t; i>=0; i--) {
            printf("%d",FRoad[i]);
            if(i)
                printf(" => ");
        }
        printf("\n");
        printf("Distance = %d: ",G[s][d].length);
        for(i=k; i>=0; i--) {
            printf("%d",LRoad[i]);
            if(i)
                printf(" => ");
        }
    }
}

原文地址:https://www.cnblogs.com/snzhong/p/12539749.html

时间: 2024-11-09 07:55:09

进阶实验6-3.3 天梯地图 (30分)-Dijkstra的相关文章

进阶实验6-3.2 社交网络图中结点的“重要性”计算 (30分)-dijkstra算法

解题思路:(邻接矩阵存储) 用dijkstra算法依次求出每个结点到其余结点的最短距离 #include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MaxVex 1000+10 int G[MaxVex][MaxVex]; int visit[MaxVex]; int Nv,Ne; void Init() { memset(G,INF,sizeof(G)); int i; for(i=1; i<=

进阶实验6-3.6 最小生成树的唯一性 (35分)

给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一.本题就要求你计算最小生成树的总权重,并且判断其是否唯一. 输入格式: 首先第一行给出两个整数:无向图中顶点数 N(≤)和边数 M.随后 M 行,每行给出一条边的两个端点和权重,格式为“顶点1 顶点2 权重”,其中顶点从 1 到N 编号,权重为正整数.题目保证最小生成树的总权重不会超过 2?30??. 输出格式: 如果存在最小生成树,首先在第一行输出其总权重,第二行输出“Yes”,如果此树唯一,否则输出“No”.如

天梯地图

L3-007 天梯地图 (30 分) 本题要求你实现一个天梯赛专属在线地图,队员输入自己学校所在地和赛场地点后,该地图应该推荐两条路线:一条是最快到达路线:一条是最短距离的路线.题目保证对任意的查询请求,地图上都至少存在一条可达路线. 输入格式: 输入在第一行给出两个正整数N(2 ≤ N ≤ 500)和M,分别为地图中所有标记地点的个数和连接地点的道路条数.随后M行,每行按如下格式给出一条道路的信息: V1 V2 one-way length time 其中V1和V2是道路的两个端点的编号(从0

pta08-图7 公路村村通 (30分)

08-图7 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N):随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本.为简单起见,城镇从1到N编号. 输出格式: 输出村村通需要的最低成本.如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路. 输入样例: 6

PTA 07-图5 Saving James Bond - Hard Version (30分)

07-图5 Saving James Bond - Hard Version   (30分) This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured by a group of drug dealers. He was sent to a small piece of lan

5-10 公路村村通 (30分)

5-10 公路村村通   (30分) 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数NN(\le 1000≤1000)和候选道路数目MM(\le 3N≤3N):随后的MM行对应MM条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本.为简单起见,城镇从1到NN编号. 输出格式: 输出村村通需要的最低成本.如果输入数据不足以保证畅通,则输出-1?1,

pta5-9 Huffman Codes (30分)

5-9 Huffman Codes   (30分) In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem o

mycat基础实验之主从配置读写分离和分表

mycat实验之主从配置读写分离和分表 架构图: 1.实验环境: vmware虚机3个   (虚机太少了,电脑有点吃力,3个虚机只能达到基本的测试) 系统centos7     (实验是关闭防火墙和selinux做的) mysql版本5.7 mycat版本1.6 虚机名字和ip: mysql1 192.168.211.138 mysql2 192.168.211.139 mysql3 192.168.211.142 mycat安装在mysql1(192.168.211.138) 这台主机须能够解

7-11 关键活动(30 分)

7-11 关键活动(30 分) 假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行."任务调度"包括一组子任务.以及每个子任务可以执行所依赖的子任务集. 比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务.有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修哪门的约束:有些课程则不可以同时开设,因为它们有先后的依赖关系,比如C程序设计和数据结构两门课,必须先学习前者. 但是需要