【[JLOI2011]飛行路線】
阿新 • • 發佈:2019-01-02
據說這是分層圖最短路的板子題
但其實就是一個\(dij\)多帶了一維狀態
我們看到\(k\)很小所以顯然我們可以設計一個這樣的狀態
\(d[v][k]\)表示從起點到點\(v\)免費走了\(k\)條路的最短路是多少
之後向下轉移(即普通\(dij\)裡的鬆弛)也很簡單,就是有兩種選澤,一種是這條路免費走,還有就是這條路不免費走
之後就很簡單了
程式碼
#include<queue> #include<cstdio> #include<iostream> #include<cstring> #define re register #define maxn 100001 #define to second.first #define pre second.second #define mp make_pair #define inf 99999999999 #define int long long using namespace std; typedef pair<int,int> pi; typedef pair<int,pi> pii; priority_queue<pii,vector<pii>,greater<pii> > q; struct eee { int v,nxt,w; }e[maxn*10]; int d[maxn][21],n,m,head[maxn],num; int f[maxn][21],t; inline void add_edge(int x,int y,int z) { e[++num].v=y; e[num].nxt=head[x]; e[num].w=z; head[x]=num; } inline int read() { char c=getchar(); int x=0; while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar(); return x; } inline void dijkstra(int s) { for(re int i=0;i<n;i++) for(re int j=0;j<=t;j++) d[i][j]=inf; d[s][0]=0; q.push(mp(0,mp(s,0))); while(!q.empty()) { int k=q.top().to; int pk=q.top().pre; q.pop(); if(f[k][pk]) continue; f[k][pk]=1; for(re int i=head[k];i;i=e[i].nxt) { if(d[e[i].v][pk]>d[k][pk]+e[i].w) { d[e[i].v][pk]=d[k][pk]+e[i].w; q.push(mp(d[e[i].v][pk],mp(e[i].v,pk))); } if(pk+1<=t&&d[e[i].v][pk+1]>d[k][pk]) { d[e[i].v][pk+1]=d[k][pk]; q.push(mp(d[e[i].v][pk+1],mp(e[i].v,pk+1))); } } } } signed main() { n=read(); m=read(); t=read(); int x,y,z; int ss=read(),tt=read(); for(re int i=1;i<=m;i++) { x=read(); y=read(); z=read(); add_edge(x,y,z); add_edge(y,x,z); } dijkstra(ss); int ans=inf; for(re int i=0;i<=t;i++) ans=min(ans,d[tt][i]); printf("%d\n",ans); return 0; }