1003. Emergency

来源:互联网 发布:拉货搬家软件 编辑:程序博客网 时间:2024/06/05 21:15

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) - the number of cities (and the cities are numbered from 0 to N-1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.
All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input
5 6 0 21 2 1 5 30 1 10 2 20 3 11 2 12 4 13 4 1
Sample Output
2 4 

算法:

  1. 算法开始。
  2. 定义结构体city,内含变量visited,0代表未被访问,1代表已被访问,n_rescue代表C1到该城市最短路径中可获得救援队最大的数量,d代表C1到该城市的最短距离。
  3. 读入N、M、C1、C2。
  4. 读入N个城市的救援队数量,存储于数组rescue。
  5. 依次读入ai、bi城市之间的公路长度,存储于邻接矩阵matrix。
  6. 设置count数组,存储C1到第i个城市的最短路径数量。设置city类型名为list数组,存储N个城市的信息,并把d全部设为INT_MAX。
  7. 令list[C1].n_rescue=rescue[C1],list[C1].d=0。
  8. 当i小于N时,继续,否则跳到第十七步。
  9. 找到未被访问城市中d最小的城市,赋值给u,把u设置为已访问。
  10. 如果j小于N时,继续,否则跳到第十六步。
  11. 如果第j个城市未被访问,而且该城市与u有公路连接,进行第第十二步,否则进行第十五步。
  12. 如果第j个城市的d大于u的d加上j、u之间距离之和,那么j的d等于u的d加上j、u之前的距离,j的n_rescue等于rescue[j]加上u的n_rescue,count[j]=count[u]。进行第十五步。
  13. 如果第j个城市的d等于u的d加上j、u之间距离之和,那么第j个城市最短路径数量等于第j个城市最短路径数量加上第u个城市最短路径数量,进行第十四步。
  14. 如果j的n_rescue小于rescue[j]加上u的n_rescue,j的n_rescue等于rescue[j]加上u的n_rescue。进行第十五步。
  15. j加一,回到第十步。
  16. i++,回到第八步。
  17. 输出C1到C2城市的最短路径数量和救援队数量。
  18. 算法结束。
提示:Dijkstra算法。
#include <stdio.h>#include <stdlib.h>#include <memory.h> #include <limits.h>typedef struct city{    int n_rescue;    int visited;    int d;} city;void Dijkstra(city* list, int* rescue, int* count, int n);int find_min(city* list, int* rescue, int n);int** matrix;int c1, c2;int main(int argc, const char * argv[]) {    int n, m, i, distance, p1, p2;    int *rescue, *count;    city *list;        scanf("%d %d %d %d", &n, &m, &c1, &c2);        list = (city*)calloc(n, sizeof(city));    matrix = (int**)calloc(n, sizeof(int*)); /* adjacent matrix */    rescue = (int*)calloc(n, sizeof(int));   /* the number of rescue teams in cities */    count = (int*)calloc(n, sizeof(int));    /* the number of shortest paths from c1 to i */    for(i = 0; i < n; i++){        list[i].d = INT_MAX;    }    list[c1].d = 0;    for(i = 0; i < n; i++){        matrix[i] = (int*)calloc(n, sizeof(int));        memset(matrix[i], -1, sizeof(int) * n);         /* -1 means that there is no road between i and j city */    }    for(i = 0; i < n; i++){        scanf("%d", rescue + i);  /* rescue[i] represents the number of rescue teams in ith city */    }    for(i = 0; i < m; i++){        scanf("%d %d %d", &p1, &p2, &distance);        matrix[p1][p2] = distance;        matrix[p2][p1] = distance;    }    Dijkstra(list, rescue, count, n);    printf("%d %d\n", count[c2], list[c2].n_rescue);    return 0;}void Dijkstra(city* list, int* rescue, int* count, int n){    int i, j, u;    list[c1].d = 0;    list[c1].n_rescue = rescue[c1];    count[c1] = 1;    for(i = 0; i < n; i++){        u = find_min(list, rescue, n);        for(j = 0; j < n; j++){            if(matrix[u][j] != -1 && list[j].visited != 1){                if(matrix[u][j] + list[u].d < list[j].d){                    list[j].d = list[u].d + matrix[u][j];                    list[j].n_rescue = rescue[j] + list[u].n_rescue;                    count[j] = count[u];                }                else if(matrix[u][j] + list[u].d == list[j].d){                    if(list[j].n_rescue < rescue[j] + list[u].n_rescue){                        list[j].n_rescue = rescue[j] + list[u].n_rescue;                    }                    count[j] += count[u];                }            }        }    }}int find_min(city* list, int* rescue, int n){    int i, u = -1, min;    min = INT_MAX;    for(i = 0; i < n; i++){        if(!(list[i].visited) && list[i].d < min){            min = list[i].d;            u = i;        }    }    if(u == -1){        exit(1);    }    list[u].visited = 1;    return u;}


0 0
原创粉丝点击