1. 程式人生 > >【[JLOI2011]飛行路線】

【[JLOI2011]飛行路線】

據說這是分層圖最短路的板子題

但其實就是一個\(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;
}