题目:https://www.luogu.org/problem/P4822
有 N 个城市,M 条双向的道路。城市编号为 1~N,我们在 1 号城市,需要到 N 号城市,怎样才能最快地到达呢?
现在,我们一共有 K 张可以使时间变慢 50%的 SpellCard,也就是说,在通过某条路径时,我们可以选择使用一张卡片,这样,我们通过这一条道路的时间 就可以减少到原先的一半。需要注意的是:
- 在一条道路上最多只能使用一张 SpellCard。
- 使用一张SpellCard 只在一条道路上起作用。
- 你不必使用完所有的 SpellCard。
给定以上的信息,你的任务是:求出在可以使用这不超过 K 张时间减速的 SpellCard 之情形下,从城市1 到城市N最少需要多长时间。
代码:
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
const int INF = 0x3f3f3f3f;
const int MAXN = 3000;
const int MAXM = 1e5 * 3;
int n, m, k;
struct Edge
{
int to, w, nxt;
}edge[MAXM];
int head[MAXN], t = 1;
void init()
{
memset(head, -1, sizeof(head));
t = 1;
}
void add(int u, int v, int w)
{
edge[t].to = v;
edge[t].w = w;
edge[t].nxt = head[u];
head[u] = t++;
}
int dis[MAXN], book[MAXN];
void dijkstra()
{
memset(dis, INF, sizeof(dis));
memset(book, 0, sizeof(book));
dis[1] = 0;
priority_queue<pii, vector<pii>, greater<pii> > q;
q.push({dis[1],1});
while(!q.empty())
{
int u = q.top().second;
q.pop();
if(book[u]) continue;
book[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].nxt)
{
int to = edge[i].to;
int w = edge[i].w;
if(!book[to] && dis[to] > dis[u] + w)
{
dis[to] = dis[u] + w;
q.push({dis[to], to});
}
}
}
}
int main()
{
cin >> n >> m >> k;
init();
int a, b, c;
while(m--)
{
cin >> a >> b >> c;
for(int i = 0; i <= k; i++)
{
add(a + i * n, b + i * n, c);
add(b + i * n, a + i * n, c);
if(i != k)
{
add(a + i * n, b + (i + 1) * n, c/2);
add(b + i * n, a + (i + 1) * n, c/2);
}
}
}
dijkstra();
int ans = INF;
for(int i = 0; i <= k; i++)
{
// cout << dis[n + i * n] << endl;
ans = min(ans, dis[n + i * n]);
}
cout << ans << endl;
return 0;
}
该博客讨论了如何解决P4822编程题目,即在一个包含N个城市和M条双向道路的网络中,从城市1到城市N寻找最短路径。问题中引入了K张能将通行时间减半的SpellCard,每条道路最多使用一次。博主分享了如何在考虑SpellCard使用策略的情况下,找到从起点到终点的最短时间。文章包含问题描述和代码实现。
331

被折叠的 条评论
为什么被折叠?



