列表

详情


NC25558. 西湖奇遇记Ⅰ

描述

鸡尾酒在去西湖的路上遇到了两个可爱的妹子,妹子邀请他一起逛西湖。但是西湖周边的景点太多了,还有许多道路让人眼花缭乱。初始鸡尾酒和妹子在第1个景点,妹子的目标是第N个景点。其中一些景点间有双向道路连接,也有一些景点间没有路,经过每条路都要消耗一定的时间。鸡尾酒不在意中间这些景点,他只想最快的领妹子到第N的景点。他带的钱可以带他和妹子乘坐k次观光车,观光车可以使他从某一个景点到另一个景点的时间消耗变为1(前提是两个景点间有直达的道路)

求鸡尾酒从点1走到点N的最短时间。

输入描述

输入第一行给两个正整数N,M, K(1<=N,M<=1e5,1<=k<=5)代表有N个点,M条路径,可以乘坐k次观光车

接下来M行,每行给出三个整数a b c,代表a b两点间有一条路,需要时间c才能通过。(1<=a,b <= N, 1<=c <= 1e9)

输出描述

输出一行一个整数表示答案

示例1

输入:

3 3 1
1 2 3
2 3 3
1 3 100

输出:

1

说明:

可以乘坐1次观光车,直接从1到3,消耗时间为1

原站题解

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

C++11(clang++ 3.9) 解法, 执行用时: 1127ms, 内存消耗: 30688K, 提交时间: 2019-05-11 16:09:24

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
constexpr int maxn = 2e5;
constexpr int maxk = 7;
vector<pair<int, LL> > G[maxn];
LL d[maxn * maxk];
bool done[maxn * maxk];
priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<pair<LL, int>>> q;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n, m, k;
	cin >> n >> m >> k;
	for(int i = 1; i <= m; i += 1){
		int a, b, c;
		cin >> a >> b >> c;
		a -= 1, b -= 1;
		G[a].push_back(make_pair(b, c));
		G[b].push_back(make_pair(a, c));
	}
	fill(d, d + maxn * maxk, 1e18);
	q.push({d[0] = 0, 0});
	while(not q.empty()){
		int u = q.top().second;
		q.pop();
		if(done[u]) continue;
		done[u] = true;
		for(const auto &p : G[u % n]){
			int v = p.first + u / n * n, w = p.second;
			if(d[v] > d[u] + w) q.push({d[v] = d[u] + w, v}); 
		}
		if(u / n < k) for(const auto &p : G[u % n]){
			int v = p.first + u / n * n + n;
			if(d[v] > d[u] + 1) q.push({d[v] = d[u] + 1, v}); 
		}
	}
	LL ans = 1e18;
	for(int j = 0; j <= k; j += 1)
		ans = min(ans, d[j * n + n - 1]);
	cout << ans;
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 527ms, 内存消耗: 49204K, 提交时间: 2019-11-10 16:39:18

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
#define ll long long 
int n,m,k;
struct node 
{
	int v,w;
};
vector<node>G[N];
struct node1
{
	int v,k;
	ll w; 
	bool operator<(const node1&p) const
	{
		return w>p.w;
	};
} ;
ll d[N][10];
ll dfs()
{
	priority_queue<node1>q;
	while(q.size())q.pop();
	for(int i=1;i<=n;i++) for(int j=0;j<=k;j++) d[i][j]=0x3f3f3f3f3f3f3f3f;
	q.push({1,0,0});
	d[1][0]=0;
	while(q.size())
	{
		node1 t=q.top();
		q.pop();
		int u=t.v;
		if(t.v==n) return t.w;
		for(int i=0;i<G[u].size();i++)
		{
			int v=G[u][i].v;
			int w=G[u][i].w;
			if(d[v][t.k]>d[u][t.k]+w)
			{
				d[v][t.k]=d[u][t.k]+w;
				q.push({v,t.k,d[v][t.k]});
			}
			if(t.k+1<=k)
			{
				if(d[v][t.k+1]>d[u][t.k]+1)
				{
					d[v][t.k+1]=d[u][t.k]+1;
					q.push({v,t.k+1,d[v][t.k+1]});
				}
			}
		}
	} 
}
int main()
{
	
	cin>>n>>m>>k;
	for(int i=1;i<=m;i++)
	{
		int x,y,w;
		cin>>x>>y>>w;
		G[x].push_back({y,w});
		G[y].push_back({x,w});
	}
	cout<<dfs()<<endl;
	return 0;
}

上一题