问题描述
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, 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 Specification:
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 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
这道题我用了Dijkstra 算法 当然算法需要改进一下,这道题才能用 。
我在vs2017上跑了该程序结果没问题
但是在pat的编译器上跑,有几个测试点没有通过,看下图
看来程序仍有改进的余地。恳请各位指证。我对我的代码进行了较为详细的注释,把我认为几个坑的地方列上来。希望能对各位有所帮助。
#include<iostream>
#include<limits.h>
#include<stdlib.h>
#include<vector>
using namespace std;
struct Dis {
int weight;//权重
int max_rescue_num;//从源节点到该节点 最大救援队数
//int pathnum;//从源节点到该节点 最短路径的总数
vector<int> father;//用于记录父亲节点
bool visit;//是否被访问
Dis() {
weight = INT_MAX;
max_rescue_num = 0;
visit = false;
}
};
int main() {
int city_num, road_num, begin_city, end_city;
vector<int>city_rescue_team_num;
int** Map;
cin >> city_num >> road_num >> begin_city >> end_city;//输入
Dis* dis = new Dis[city_num];
Map = new int *[city_num];
for (int i = 0; i < city_num; i++)
{
Map[i] = new int[city_num];
for (int j = 0; j < city_num; j++)
Map[i][j] = INT_MAX;//该循环初始化了地图,全部设成无穷大
}
for (int i = 0; i < city_num; i++)
{
int linshi = 0;
cin >> linshi;//输入
city_rescue_team_num.push_back(linshi);
}//改循环完成了对城市救援队数目的初始化
for (int i = 0; i < road_num; i++)
{
int temp_begin;
int temp_end;
int temp_weight;
cin >> temp_begin >> temp_end >> temp_weight;
Map[temp_begin][temp_end] = temp_weight;
Map[temp_end][temp_begin] = temp_weight;//这样是因为默认 该图是无向图
}//该循环对路径进行标记权重
/**********************分割线**********************/
/**********************分割线**********************/
/**********************分割线**********************/
//dijkstra算法处理 核心
dis[begin_city].weight = 0;
dis[begin_city].visit = true;
dis[begin_city].father.push_back(-1);//开始节点的父亲设为-1 意思没有父亲
dis[begin_city].max_rescue_num = city_rescue_team_num[begin_city];
for (int i = 0; i < city_num; i++)
{
if (dis[i].visit == false && Map[begin_city][i] != INT_MAX)
{
dis[i].weight = Map[begin_city][i];
dis[i].father.push_back(begin_city);
dis[i].max_rescue_num = dis[begin_city].max_rescue_num + city_rescue_team_num[i];
}
}//dis第一次的状态 单独处理,至此第一次的dis数组初始化完毕 ,下面进入关键循环
/***************************************************/
for (int byh = 1;byh <city_num; byh++)//循环这么些次即退出
{
int min=INT_MAX;//记录最短路径,并初始化为无穷
int temp;//记录最短路径dis的下标
for (int i = 0; i < city_num; i++)
{
if (dis[i].visit == false && dis[i].weight <min)
{
min = dis[i].weight;
temp = i;
}
}//找最小路径节点
dis[temp].visit = true;//找到了最短路径节点,标记为已访问
for (int j = 0; j < city_num; j++)//该循环通过中间最小路径更新dis数组
{
if ( dis[temp].weight + Map[temp][j]<dis[j].weight && dis[j].visit==false && Map[temp][j]!=INT_MAX)
//注意 坑点 Map[temp][j]!=INT_MAX 要这个条件没加,会数据溢出,算法整个垮掉
{
dis[j].weight = dis[temp].weight + Map[temp][j];//更新最短路径
dis[j].max_rescue_num = dis[temp].max_rescue_num + city_rescue_team_num[j];
if (dis[j].father.size() == 0)
{
dis[j].father.push_back(temp);
}
else
{
dis[j].father.pop_back();
dis[j].father.push_back(temp);
}
}
else if (dis[j].weight == dis[temp].weight + Map[temp][j] && dis[j].visit == false&& Map[temp][j] != INT_MAX)
//注意 坑点 Map[temp][j]!=INT_MAX 要这个条件没加,会数据溢出,算法整个垮掉
{
dis[j].father.push_back(temp);
if (dis[j].max_rescue_num < dis[temp].max_rescue_num + city_rescue_team_num[j])
dis[j].max_rescue_num = dis[temp].max_rescue_num + city_rescue_team_num[j];
}
}
}
/**********************分割线**********************/
/**********************分割线**********************/
printf("%d %d", dis[end_city].father.size(), dis[end_city].max_rescue_num);//输出结果
/*cin.get();
cin.get();*/ //vs2017需要加cin.get() 否则闪退
return 0;
}