• PTA数据结构与算法题目集(中文) 7-35 城市间紧急救援 (25 分)


    PTA数据结构与算法题目集(中文)  7-35 城市间紧急救援 (25 分)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

    输入格式:

    输入第一行给出4个正整数N、M、S、D,其中N(2)是城市的个数,顺便假设城市的编号为0 ~ (;M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。

    第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

    输出格式:

    第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。

    输入样例:

    4 5 0 3
    20 30 40 10
    0 1 1
    1 3 2
    0 3 3
    0 2 2
    2 3 2
    

    输出样例:

    2 60
    0 1 3
    题目分析:一道图的单源有权最短路径题 利用Dijkstra算法 该题中有2个决定性因素 所以优先判断的那个 要更新次重要的那个因素
    再者,计算最短路径的条数 要注意计算的方法 是利用前一个节点与后一个节点之间的关系来计算 具体来说 对于每一个找到最小路径的节点,它最短路径的次数与它前一个节点的最短路径次数相同,如果找到了另一种最短路径,那么总的最短路径次数要加上其另一种最短路径的上一个节点最短路径的次数
    最后,在输出路径时 要利用到栈,仔细想想,递归也是用类似于栈的思想来实现的,所以可以用递归来实现输出
      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<malloc.h>
      5 #define INIFITY 65535
      6 typedef struct ENode* Edge;
      7 struct ENode
      8 {
      9     int V1,V2;
     10     int Weight;
     11 };
     12 typedef struct GNode* Graph;
     13 struct  GNode
     14 {
     15     int G[510][510];
     16     int Nv;
     17     int Ne;
     18 };
     19 
     20 int IsEdge(Graph Gra, int V1, int V2)
     21 {
     22     return Gra->G[V1][V2]!=INIFITY;
     23 }
     24 
     25 void Insert(Graph Gra, Edge E)
     26 {
     27     Gra->G[E->V1][E->V2] = E->Weight;
     28     Gra->G[E->V2][E->V1] = E->Weight;
     29 }
     30 
     31 Graph CreateGraph(int Nv)
     32 {
     33     Graph Gra = (Graph)malloc(sizeof(struct GNode));
     34     Gra->Nv = Nv;
     35     Gra->Ne = 0;
     36     for (int i = 0; i < Gra->Nv; i++)
     37         for (int j = 0; j < Gra->Nv; j++)
     38             Gra->G[i][j] = INIFITY;
     39     return Gra;
     40 }
     41 
     42 int WeightInNode[510];
     43 int SumOfWeight[510];
     44 
     45 int Dist[510];
     46 int Path[510];
     47 int Times[510];
     48 int Collected[510];
     49 int FindMinDist(Graph Gra)
     50 {
     51     int MinDist = INIFITY;
     52     int Min = -1;
     53     for (int i = 0; i < Gra->Nv; i++)
     54     {
     55         if (!Collected[i]&&Dist[i] < MinDist)
     56         {
     57             MinDist = Dist[i];
     58             Min = i;
     59         }
     60     }
     61     if (MinDist != INIFITY)
     62         return Min;
     63     else
     64         return 0;
     65 }
     66 
     67 void Dijkstra(Graph Gra, int V)
     68 {
     69     SumOfWeight[V] = WeightInNode[V];
     70     for (int i = 0; i < Gra->Nv; i++)
     71     {
     72         Dist[i] = Gra->G[V][i];
     73         if (IsEdge(Gra, V, i))
     74         {
     75             SumOfWeight[i] = SumOfWeight[V] + WeightInNode[i];
     76             Path[i] = V;
     77             Times[i] = 1;
     78         }
     79         else        
     80             Path[i] = -1;
     81     }
     82 
     83     Dist[V] = 0;
     84     Collected[V] = 1;
     85     while (1)
     86     {
     87         int i = FindMinDist(Gra);
     88         if (!i)
     89             break;
     90         Collected[i] = 1;
     91         for (int j = 0; j < Gra->Nv; j++)
     92         {
     93             if(!Collected[j]&&IsEdge(Gra,i,j))
     94                 if (Dist[i] + Gra->G[i][j] < Dist[j])
     95                 {
     96                     Times[j] = Times[i];
     97                     Dist[j] = Dist[i] + Gra->G[i][j];
     98                     SumOfWeight[j] = SumOfWeight[i] + WeightInNode[j];
     99                     Path[j] = i;
    100                 }
    101                 else if (Dist[i] + Gra->G[i][j] == Dist[j])
    102                 {
    103                     Times[j] += Times[i];
    104                     if (SumOfWeight[i] + WeightInNode[j] >=SumOfWeight[j])
    105                     {
    106                         SumOfWeight[j] = SumOfWeight[i] + WeightInNode[j];
    107                         Path[j] = i;
    108                     }
    109                 }
    110         }
    111     }
    112 }
    113 
    114 int k = 0;
    115 void Print(int D)
    116 {
    117     if (Path[D] != -1)
    118     {
    119         Print(Path[D]);
    120     }
    121     if (k == 0)
    122     {
    123         printf("%d", D);
    124         k++;
    125     }
    126     else
    127         printf(" %d",D);
    128 }
    129 
    130 int main()
    131 {
    132     int N, M, S, D;
    133     scanf("%d%d%d%d", &N, &M, &S, &D);
    134     Graph Gra = CreateGraph(N);
    135     Gra->Ne = M;
    136     for (int i = 0; i < Gra->Nv; i++)
    137         scanf("%d", &WeightInNode[i]);
    138     Edge E = (Edge)malloc(sizeof(struct ENode));
    139     for (int i = 0; i < Gra->Ne; i++)
    140     {
    141         scanf("%d%d%d", &(E->V1), &(E->V2), &(E->Weight));
    142         Insert(Gra, E);
    143     }
    144     Dijkstra(Gra, S);
    145     printf("%d %d
    ", Times[D], SumOfWeight[D]);
    146     Print(D);
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    「消息队列」看过来!
    stl中map的四种插入方法总结
    4.shell编程-文本处理三剑客之sed
    3.shell编程-文件查找之find命令
    2.shell编程-函数的高级用法
    1.shell编程-变量的高级用法
    Django打造大型企业官网(八)
    Django打造大型企业官网(七)
    Django打造大型企业官网(六)
    Django打造大型企业官网(五)
  • 原文地址:https://www.cnblogs.com/57one/p/11665896.html
Copyright © 2020-2023  润新知