基于分层图的最短路
对于分成图建图的时候如果真要建的话一定要注意层与层之间是单向路而且一个边的两个端点都要建边,通常我们范的错误就是只建from->to的一条一定不要忘了to->from 这题很简单就是一个dp+最短路,不用建图但思想一样
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
struct nodee
{
int name, kind;
ll dis;
};
nodee node[20000];
int first[20000], nextt[150000];
ll dis[20000][21];
int n, m, k;
struct edgee
{
int from, to;
ll dis;
edgee(int from, int to, ll dis) :from(from), to(to), dis(dis)
{}
edgee()
{}
};
edgee edge[150000];
int edgetot;
void addedge(int from, int to, ll dis)
{
edge[edgetot] = edgee(from, to, dis);
nextt[edgetot] = first[from];
first[from] = edgetot++;
edge[edgetot] = edgee(to, from, dis);
nextt[edgetot] = first[to];
first[to] = edgetot++;
}
struct com
{
bool operator()(nodee a, nodee b)
{
return a.dis > b.dis;
}
};
void distra()
{
priority_queue < nodee, vector<nodee>, com > que;
dis[1][1] = 0;
nodee a;
a.dis = 0; a.kind = 1; a.name = 1;
que.push(a);
while (!que.empty())
{
nodee now = que.top();
que.pop();
if (now.dis > dis[now.name][now.kind])
continue;
for (int i = first[now.name]; i != -1; i = nextt[i])
{
int to = edge[i].to;
if (dis[to][now.kind] > dis[now.name][now.kind]+edge[i].dis)
{
dis[to][now.kind] = dis[now.name][now.kind] + edge[i].dis;
nodee c;
c.dis = dis[to][now.kind];
c.kind = now.kind;
c.name = to;
que.push(c);
}
if (dis[to][now.kind + 1] > dis[now.name][now.kind] && now.kind + 1<=k)
{
nodee c;
dis[to][now.kind + 1] = dis[now.name][now.kind];
c.name = to;
c.dis = dis[now.name][now.kind];
c.kind = now.kind + 1;
que.push(c);
}
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
k++;
for (int i = 1; i <= n; i++)
first[i] = -1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= k; j++)
dis[i][j] = 1000000000000;
}
for (int i = 0; i < m; i++)
{
int a, b;
ll c;
scanf("%d%d%lld", &a, &b, &c);
addedge(a, b, c);
}
distra();
printf("%lld\n", dis[n][k]);
return 0;
}