PAT(甲级)1003 Emergency (25 分)

题目来源: 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;
}

我的翼德哥哥认真看嗷

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值