PAT 1003

1003 Emergency (25分)


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 Specification:

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, C​1​​ and C​2​​ - 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 c​1​​, c​2​​ 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 C​1​​ to C​2​​.

Output Specification:

For each test case, print in one line two numbers: the number of different shortest paths between C​1​​ and C​2​​, 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 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:

2 4

一、试题分析: 

  1. 题目要求出:最短路径的数目、最多救援人手数量
  2. 考察内容:图的搜索方法(迪杰斯特拉算法DFS求最短路径)

二、解题思路: 

  • 根据题意设置相关变量(有些变量需要设置为全局变量,供其他函数使用)
  • 迪杰斯特拉使用深度优先搜索算法求最短路径的思路:
  • 初始化:
  1. 图的邻接矩阵road[][] = INT_MAX(不可达)—— #include <climits>
  2. 监视哨visited[] = 0(未访问状态)
  • 深度优先搜索:dfs(c1,c2,distance,hands)
  1. 到达最后一个点 c1==c2:更新最短路径、最短路径数目、最多人手
  2. 未到达最后一个点:中途若路径长度已经超过最短路径长度则直接返回——减少运行时间
  3. 循环查找未访问可达的点:遍历继续深度搜索
  4. 当遍历完毕后回溯:visited[] = 0
#include <iostream>
#include <climits>
using namespace std;

int rescue[501]; //每个城市救援团队数目
int road[501][501]; //城市之间的路径长度
int visited[501]; //记录是否被访问
int n; //城市数
int mindistance=INT_MAX; //最短路径长度
int count; // 最短路径数目
int allhands; //最多人手数目

//初始化访问数组为未访问状态、道路数组为不可达
void init(){
    for(int i=0;i<n;i++){
        visited[i]=0;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            road[i][j]=INT_MAX; //不可达
        }
    }
}

//深度优先搜索
void dfs(int c1,int c2,int distance,int hands){
    if(c1==c2){ //到达终点
        if(distance<mindistance){ //有更短的路径
            count=1;
            mindistance=distance;
            allhands=hands; //直接更新救援队数目
        }else if(distance==mindistance){ //最短路径相同
            count++;
            if(allhands<hands){ //更新最多的救援队数目
                allhands=hands;
            }
        }
        return;
    }

    if(distance>mindistance)//中途只要比最短距离长,则返回
        return;

    for(int i=0;i<n;i++){
        if(visited[i]==0&&road[c1][i]!=INT_MAX){//未被访问且可达
            visited[i]=1;
            dfs(i,c2,distance+road[c1][i],hands+rescue[i]); //深度优先搜索
            visited[i]=0; //回溯
        }
    }
}
//迪杰斯特拉求最短路径
int main()
{
    int m; //道路数
    int c1,c2; //原点、终点

    int x,y;
    int distance;

    cin>>n>>m>>c1>>c2;

    for(int i=0;i<n;i++){
        cin>>rescue[i];
    }
    init();
    for(int i=0;i<m;i++){
        cin>>x>>y>>distance;
        road[x][y]=road[y][x]=distance;
    }
    dfs(c1,c2,0,rescue[c1]);
    cout<<count<<' '<<allhands;
    return 0;
}

 

发布了19 篇原创文章 · 获赞 2 · 访问量 6149
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览