题目链接:https://www.luogu.org/problemnew/show/P4568
典型的分层图的题,因为k的取值范围很小,所以我们需要另外再建立k层图,其实就是相当于跨层建边,主要就是这个过程怎么实现,剩下的就是一个裸的dij了。看到一份用二维数组存的代码,感觉要比我的代码写的简单,过两天敲一下试试,传送门
AC代码:
#include <bits/stdc++.h>
#define maxn 1200100
#define ll long long
using namespace std;
struct node{
int next;
int to;
int val;
}Edge[maxn << 1];
struct Node{
int val,cnt;
bool operator < (const Node &a) const {
if(a.val == val) return a.cnt < cnt;
return a.val < val;
}
}Next,Now;
int n,m,k,s,e;
int head[maxn],num,dist[maxn];
bool vis[maxn];
priority_queue<Node> q;
void init(){
memset(head,-1,sizeof(head));
num = 0;
}
void add(int u,int v,int val){
Edge[num].to = v;
Edge[num].val = val;
Edge[num].next = head[u];
head[u] = num++;
}
void dijkstra(){
memset(vis,false,sizeof(vis));
memset(dist,0x3f,sizeof(dist));
Now.val = 0;
Now.cnt = s;
dist[s] = 0;
q.push(Now);
while(!q.empty()){
Now = q.top();
q.pop();
int flag = Now.cnt;
if(vis[flag])continue;
vis[flag] = true;
for(int i=head[flag]; i != -1; i = Edge[i].next){
int u = Edge[i].to;
if(!vis[u] && dist[u] > dist[flag] + Edge[i].val){
dist[u] = dist[flag] + Edge[i].val;
Next.cnt = u;
Next.val = dist[u];
q.push(Next);
}
}
}
int ans = 0x3f3f3f3f;
for(int i=0;i<=k;i++){
ans = min(ans, dist[e + i * n]);
}
printf("%d\n",ans);
}
int main()
{
init();
scanf("%d%d%d",&n,&m,&k);
scanf("%d%d",&s,&e);
s++;e++;
for(int i=0;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
u++;v++;
for(int j=0;j<=k;j++){
add(u+j*n, v+j*n, w);
add(v+j*n, u+j*n, w);
if(j != k){
add(u+j*n, v+(j+1)*n, 0);
add(v+j*n, u+(j+1)*n, 0);
}
}
}
dijkstra();
return 0;
}