分层图最短路
1.单源最短路径+k次瞬间转移(路径值为0)
spfa版本,注意是单向边啊啊
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) using namespace std; const int M=10050; const int K=15; const int N=10050; const int inf=0x3f3f3f3f; int head[N],tot; struct node{int v,w,next;}e[M<<1]; void insert(int u,int v,int w){ e[++tot]=(node){v,w,head[u]};head[u]=tot;} inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;} int n,m,k; int dis[K][N],vis[K][N]; int spfa(){ rep(i,0,k)rep(j,1,n) dis[i][j]=inf; memset(vis,0,sizeof vis); rep(i,0,k) dis[i][1]=0; queue<pair<int,int> > q;q.push(make_pair(1,0)); while(!q.empty()){ int u=q.front().first,t=q.front().second; q.pop();vis[t][u]=0; for(int i=head[u];i;i=e[i].next){ int v=e[i].v,w=e[i].w; if(dis[t][u]+w<dis[t][v]){ dis[t][v]=dis[t][u]+w; if(!vis[t][v]) vis[t][v]=1,q.push(make_pair(v,t));} if(dis[t][u]<dis[t+1][v]&&t<k){ dis[t+1][v]=dis[t][u]; if(!vis[t+1][v]) vis[t+1][v]=1,q.push(make_pair(v,t+1));} } }int ans=inf; rep(i,0,k) ans=min(ans,dis[i][n]);return ans; } int main(){ freopen("through.in","r",stdin); freopen("through.out","w",stdout); n=read(),m=read(),k=read(); rep(i,1,m){int u=read(),v=read(),w=read();insert(u,v,w);} printf("%d\n",spfa());return 0; }
2.SHOI2012 回家的路
建图的时候按照交汇点建图+起点和终点,由于只有xy两个维度所以直接拆点,在换乘处建立1的边即可
https://www.luogu.org/record/show?rid=10855025