题目: https://www.luogu.org/problem/P2939
约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体.
通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小径,使之成为高 速公路.在高速公路上的通行几乎是瞬间完成的,所以高速公路的通行时间为0.
请帮助约翰决定对哪些小径进行升级,使他每天从1号牧场到第N号牧场所花的时间最短
#include<bits/stdc++.h>
#define pii pair<int, int>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 9;
const int MAXM = 24100000; //双向边, 边数(M * k + N * k) * 2
//const int MAXM = 5000009 * 6;
int n, m, k;
struct Edge
{
int to, w, nxt;
}edge[MAXM];
int t;
int head[MAXN];
void init()
{
memset(head, -1, sizeof(head));
t = 1;
}
void addEdge(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)); dis[1] = 0;
memset(book, 0, sizeof(book));
priority_queue<pii, vector<pii>, greater<pii> > q;
q.push({dis[1], 1});
while(!q.empty())
{
int now = q.top().second;
q.pop();
if(book[now]) continue;
book[now] = 1;
for(int i = head[now]; i != -1; i = edge[i].nxt)
{
int to = edge[i].to;
int w = edge[i].w;
if(!book[to] && dis[to] > dis[now] + w)
{
dis[to] = dis[now] + w;
q.push({dis[to], to});
}
}
}
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
int a, b, c;
init();
while(m--)
{
scanf("%d %d %d", &a, &b, &c);
// addEdge(a, b, c);
// addEdge(b, a, c);
for(int i = 0; i <= k; i++)
{
addEdge(a + i * n, b + i * n, c);
addEdge(b + i * n, a + i * n, c);
if(i != k)
{
addEdge(a + i * n, b + (i + 1) * n, 0);
addEdge(b + i * n, a + (i + 1) * n, 0);
}
}
}
dijkstra();
int ans = INF;
for(int i = 0; i <= k; i++)
{
ans = min(ans, dis[i * n + n]);
}
printf("%d\n", ans) ;
return 0;
}
该问题描述了约翰如何通过升级部分小径成高速公路来缩短从牧场1到N的通行时间。约翰有N个牧场,M条双向小径,计划升级K条为高速,求最短时间方案。
1854

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



