\[ dis[i][j]=Min_{k{\in}pre(i)}{\{}Min(dis[k][j]+edge(k,i),dis[k][j-1]){\}} \]
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define maxn 10001
#define maxm 50001
#define maxk 21
using namespace std;
struct edge{
int to,dis,next;
edge(){}
edge(const int &_to,const int &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
}e[maxm*maxk*4];
int head[maxn*maxk],k;
int dis[maxn*maxk];
bool vis[maxn*maxk];
int n,m,q,s,t;
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v,const int &w){ e[k]=edge(v,w,head[u]),head[u]=k++; }
inline void dijkstra(){
priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;
memset(dis,0x3f,sizeof dis),dis[1]=0;
q.push(make_pair(0,1));
while(q.size()){
int u=q.top().second; q.pop();
if(vis[u]) continue; vis[u]=true;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(dis[v]>dis[u]+e[i].dis) dis[v]=dis[u]+e[i].dis,q.push(make_pair(dis[v],v));
}
}
}
int main(){
memset(head,-1,sizeof head);
n=read(),m=read(),q=read();
for(register int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
for(register int j=0;j<=q;j++) add(u+n*j,v+n*j,w),add(v+n*j,u+n*j,w);
for(register int j=1;j<=q;j++) add(u+n*(j-1),v+n*j,0),add(v+n*(j-1),u+n*j,0);
}
dijkstra();
int ans=0x3f3f3f3f;
for(register int i=0;i<=q;i++) ans=min(ans,dis[n+n*i]);
printf("%d\n",ans);
return 0;
}
[Usaco2009 Feb]Revamping Trails 道路升级
原文:https://www.cnblogs.com/akura/p/10975936.html