列表

详情


NC22594. Rinne Loves Graph

描述

Island 发生了一场暴乱!现在 Rinne 要和 Setsuna 立马到地上世界去。
众所周知:Island 是有一些奇怪的城镇和道路构成的(题目需要,游戏党勿喷),有些城镇之间用双向道路连接起来了,且每条道路有它自己的距离。但是有一些城镇已经被派兵戒严,虽然主角可以逆天改命强闯,但是为了体验该游戏的平衡性,他们只能穿过不超过 K 次被戒严的城镇。
定义“穿过”:从一个戒严的点出发到达任意一个点,都会使得次数加1
现在他们想从 1 号城镇最快的走到 n 号城镇(即出口),现在他们想让你告诉他们最短需要走多少路。

输入描述

第一行三个整数 n,m,k,分别表示城镇数量,边数量和最多能闯过被戒严的城市的次数。
接下来 n 行,每行一个整数 1 或 0,如果为 1 则表示该城市已被戒严,0 则表示相反。
接下来 m 行,每行三个数 u,v,w,表示在 u 城镇和 v 城镇之间有一条长度为 w 的双向道路。

输出描述

输出一行一个数字,表示从 1 到 n 的最短路径,如果到达不了的话,请输出 -1。

示例1

输入:

4 5 1
1
0
1
0
1 2 10
2 3 10
3 1 15
1 4 60
3 4 30

输出:

60

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 31ms, 内存消耗: 1508K, 提交时间: 2023-05-24 15:02:49

#include <bits/stdc++.h>

using i64 = std::int64_t;

constexpr i64 inf = ~0uLL >> 1;

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	int n, m, k;
	std::cin >> n >> m >> k;

	std::vector<int> a(n);
	for (int i = 0; i < n; i++) {
		std::cin >> a[i];
	}

	std::vector<std::vector<std::pair<int, int>>> adj(n);
	for (int i = 0; i < m; i++) {
		int x, y, z;
		std::cin >> x >> y >> z;
		x--, y--;	
		adj[x].emplace_back(y, z);
		adj[y].emplace_back(x, z);
	}

	std::map<std::pair<int, int>, int> vis;
	std::priority_queue<std::tuple<i64, int, int>> q;

	q.emplace(0, 0, 0);

	std::vector<i64> dist(n, inf);

	while (!q.empty()) {
		auto [d, x, cur] = q.top();
		q.pop();
		if (vis[{x, cur}]) continue;
		vis[{x, cur}] = true;
		dist[x] = std::min(dist[x], -d);

		for (auto [y, dis] : adj[x]) {
			if (vis[{y, cur + a[x]}] || cur + a[x] > k) continue;
			q.emplace(d - dis, y, cur + a[x]);
		}
	}

	std::cout << (dist[n - 1] == inf ? -1 : dist[n - 1]) << "\n";

	return 0;
}

C++14(g++5.4) 解法, 执行用时: 291ms, 内存消耗: 688K, 提交时间: 2019-11-28 21:40:33

#include<bits/stdc++.h>
using namespace std;

int i,j,w,n,m,k,V[805];
vector<int>R[805],W[805];
bool U[805];
void DFS(int x,int h,int c)
{
	int i,j,C=c+U[x];
	if(C>k)return;
	for(i=0;i<R[x].size();i++)
	{
		j=R[x][i];
		if(V[j]>h+W[x][i])V[j]=h+W[x][i],DFS(j,h+W[x][i],C);
	}
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(i=1;i<=n;i++)scanf("%d",&U[i]);
	memset(V,0x3f,sizeof(V));
	while(m--)
	{
		scanf("%d%d%d",&i,&j,&w);
		R[i].push_back(j),W[i].push_back(w);
		R[j].push_back(i),W[j].push_back(w);
	}
	V[1]=0,DFS(1,0,0);
	V[n]<1e9?printf("%d\n",V[n]):printf("-1\n");
    return 0;
}

上一题