1003 Emergency (25分)

在这里插入图片描述
利用Dijkstra最短路算法,用totalWeight记录到达某个城市时最多能搜集的救援队数,用dist表示当前到达某个城市的最短距离;用pre记录某一城市的前驱结点,即从哪个城市来。最后用dfs数出最短路数。

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int inf = 0x7fffffff;
int cityNum, roadNum, source, dest;
int weight[500];	//rescure team in each city
int map[500][500];
int dist[500];	//minimum distance to each city
int totalWeight[500];	//max rescure team gathered to a city
bool visited[500];	
vector<int> pre[500];	//come from which cities
int pathNum = 0;
void countPath(int cur) {
	if (cur == source) {
		pathNum++;
		return;
	}
	for (int i = 0;i < pre[cur].size();i++) {
		countPath(pre[cur][i]);
	}
}
int main() {
	fill(map[0], map[0] + 500 * 500, inf);
	fill(totalWeight, totalWeight + 500, 0);
	fill(dist, dist + 500, inf);
	scanf("%d %d %d %d", &cityNum, &roadNum, &source, &dest);
	for (int i = 0;i < cityNum;i++) {
		scanf("%d", &weight[i]);
	}
	for (int i = 0;i < roadNum;i++) {
		int v1, v2, len;
		scanf("%d %d %d", &v1, &v2, &len);
		map[v1][v2] = len;
		map[v2][v1] = len;
	}
	dist[source] = 0;
	totalWeight[source] = weight[source];
	for (int i = 0;i < cityNum;i++) {
		int u = -1, minDis = inf;
		for (int j = 0;j < cityNum;j++) {
			if (!visited[j] && dist[j] < minDis) {
				u = j;
				minDis = dist[j];
			}
		}
		if (u == -1 || u == dest)
			break;
		visited[u] = true;
		for (int v = 0;v < cityNum;v++) {
			if (!visited[v] && map[u][v] != inf) {
				if (dist[u] + map[u][v] < dist[v]) {
					dist[v] = dist[u] + map[u][v];
					totalWeight[v] = totalWeight[u] + weight[v];
					pre[v].push_back(u);
				}
				else if (dist[u] + map[u][v] == dist[v]) {
					pre[v].push_back(u);
					totalWeight[v] = max(totalWeight[v], weight[v] + totalWeight[u]);
				}
			}
		}
	}
	countPath(dest);
	printf("%d %d", pathNum, totalWeight[dest]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值