PAT(甲级) 1003 Emergency

题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376

代码:

	#include<iostream>
	#include<algorithm>
	#include<vector>
	#include<string>
	using namespace std;

	typedef struct Node {
		int v, w;
		Node(int a, int b) :v(a), w(b) {}
	}node;

	const int INF = 0x3f3f3f3f;
	const int MAXN = 600;
	vector<int>vis(MAXN, 0);          // 存储每个节点是否被访问
	vector<int>dis(MAXN, INF);        // 存储起始点到达每个节点的最短路径长度
	vector<int>nums(MAXN, 0);         // 存储每一个rescue teams的数量
	vector<int>num_count(MAXN, 0);    // 初始节点到每一个节点的最短路径数量
	vector<int>max_count(MAXN, 0);    // 对每一个节点获得最大的rescue teams
	vector<vector<node>>G(MAXN);      // 邻接表的方式存储无向图
	int n, m, s, e;

	//迪杰斯特拉算法
	void dijkstra() {
		//设置起始点的dis为0,且最短路径 s->s的方式只有一种
		dis[s] = 0; num_count[s] = 1;

		for (int i = 0; i < n; i++) {
			int u = -1, mmin = INF;
			//每一次选出最短距离的未访问过的节点
			for (int j = 0; j < n; j++) {
				if (vis[j] == 0 && dis[j] < mmin) {
					u = j; mmin = dis[j];
				}
			}
			if (u == -1) break;
			vis[u] = 1;
			//遍历该节点所能到达的节点,更新dis数组
			for (int j = 0; j < G[u].size(); j++) {
				int v = G[u][j].v, w = G[u][j].w;
				//由于大于和等于的操作基本一致,因此写在一起
				if (vis[v] == 0 && dis[v] >= dis[u] + w) {
					if(dis[v] == dis[u] + w){
						//到达v节点的路径数量会等于原来的数量加上从u到达的数量
						num_count[v] += num_count[u];
						//取可以获得的最大值
						max_count[v] = max(max_count[v], max_count[u] + nums[v]);
					}
					else{
						//修改dis[v]的长度
						dis[v] = dis[u] + w;
						num_count[v] = num_count[u];
						max_count[v] = max_count[u] + nums[v];
					}
				}

			}
		}
	}

	int main() {
		int a, b, c;

		cin >> n >> m >> s >> e;

		for (int i = 0; i < n; i++) cin >> nums[i];

		// 无向图
		for (int i = 0; i < m; i++) {
			cin >> a >> b >> c;
			G[a].push_back(Node(b, c));
			G[b].push_back(Node(a, c));
		}

		for (int i = 0; i < n; i++) max_count[i] = nums[i];
		dijkstra();

		cout << num_count[e] << " " << max_count[e] << endl;

		return 0;
	}

解题思路:这题是一个迪杰斯特拉的原型题上加了一些其他的问题,整体上还是一个基于迪杰斯特拉算法解决的问题。首先是问多少条最短路径,这个时候就可以用普通的迪杰斯特拉算法来求解,只有当dis[v] == dis[u] + w的时候就加上u所有的最短路径数量,如果是dis[v] > dis[u] + w的情况,那么直接把u点的最短路径数量赋值过去就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值