luogu_4568 飞行路线 分层图
题面:https://www.luogu.org/problemnew/show/P4568
大意:(见题面吧……懒得总结了。)
分层图套路题。
建k个一样的图。
不同的层之间建边权为0的单项边。
最短路直接求解。
图片来自洛谷题解。
代码如下。
#include<bits/stdc++.h> using namespace std; const int maxm=5000010; int n,m,k,s,t,head[maxm],tot; struct node{ int to,nxt,va; #define to(x) e[x].to #define nxt(x) e[x].nxt #define va(x) e[x].va }e[maxm<<1]; int dis[maxm/4];bool v[maxm/4]; inline void add(int from,int to,int w){ to(++tot)=to;va(tot)=w; nxt(tot)=head[from];head[from]=tot; } priority_queue<pair<int,int> > q; inline void dij(){ memset(dis,0x3f,sizeof(dis)); dis[s]=0; q.push(make_pair(0,s)); while(q.size()){ int now=q.top().second; q.pop(); if(v[now]) continue; for(int i=head[now];i;i=nxt(i)){ int to=to(i),w=va(i); if(dis[to]>dis[now]+w){ dis[to]=dis[now]+w; q.push(make_pair(-dis[to],to)); } } } } int main() { scanf("%d%d%d",&n,&m,&k); scanf("%d%d",&s,&t); for(int i=1;i<=m;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); for(int j=1;j<=k;j++){ add(u+j*n,v+j*n,w); add(v+j*n,u+j*n,w); add(u+(j-1)*n,v+j*n,0); add(v+(j-1)*n,u+j*n,0); } } for(int i=1;i<=k;i++) add(s+(i-1)*n,s+i*n,0); dij(); printf("%d\n",dis[t+k*n]); // system("pause"); return 0; }