题目来源: PAT(甲级)1003 Emergency (25 分)
题目描述:
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
题目翻译:
作为一个城市的紧急救援队队长,你会得到一张你所在国家的特别地图。这张地图显示了几个分散的城市,由一些道路连接起来。地图上标出了每个城市的救援队数量和任意两个城市之间每条道路的长度。当有其他城市的紧急电话打给你时,你的工作就是带领你的人尽快赶到那个地方,同时,在路上尽可能多地召集人手。
输入:
每个输入文件都包含一个测试用例。对于每个测试用例,第一行包含4个正整数:N(≤500)-城市数量(城市编号从0到N−1),M-道路数量,C1和C2-您当前所在的城市和您必须分别保存的城市。下一行包含N个整数,其中第i个整数是第i个城市的救援队数量。然后是M行,每行描述具有三个整数C1、C2、和L的道路,这三个整数分别是由道路和该道路的长度连接的城市对。保证从C1到C2至少存在一条路径。
输出:
对于每个测试用例,在一行中打印两个数字:C1和C2之间不同最短路径的数量,以及你能召集的最大数量的救援队。一行中的所有数字必须正好由一个空格分隔,并且行尾不允许有额外的空格。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 1005
#define inf 0x3f3f3f3f
int teams[maxn];//记录救援队信息
int mapp[maxn][maxn];//记录道路信息
int N, M, C1, C2;//城市数量,道路数量,起始城市,终止城市
int pathnum[maxn], tol[maxn];//分别记录道路的条数和救援队最多
int dis[maxn], book[maxn];//分别记录路径的长度
void Dijstra()
{
//memset(dis, inf, sizeof(dis));
for (int i = 0;i < N; i++)
dis[i] = inf;
dis[C1] = 0;
tol[C1] = teams[C1];
pathnum[C1] = 1;
for (int i = 0;i < N;i++)
{
int u, minn = inf;
for (int j = 0;j < N;j++)
{//查找已经更新到达该城市距离最小的城市
if (!book[j] && dis[j] < minn)
{
minn = dis[j];
u = j;
}
}
book[u] = 1;//标记即将进行遍历的点
for (int j = 0;j < N;j++)
{//计算路径边权值(距离)和救援队数量
if (dis[j] > dis[u] + mapp[u][j])
{
dis[j] = dis[u] + mapp[u][j];
tol[j] = tol[u] + teams[j];
pathnum[j] = pathnum[u];
}
else if (dis[j] == dis[u] + mapp[u][j])
{
pathnum[j] += pathnum[u];
if (tol[j] < tol[u] + teams[j])
{
tol[j] = tol[u] + teams[j];
}
}
}
}
}
int main()
{
cin >> N >> M >> C1 >> C2;
for (int i = 0;i < N;i++)//标记城市的救援队数量
cin >> teams[i];
memset(mapp, inf, sizeof(mapp));
for (int i = 0;i < M;i++)
{ //标记道路信息
int x, y, ins;
cin >> x >> y >> ins;
mapp[x][y] = mapp[y][x] = ins;
}
Dijstra();
cout << pathnum[C2] << " " << tol[C2];
return 0;
}
我的翼德哥哥认真看嗷