这道题算是一道分层图的最短路:按照天数对图进行分层,并且,在day-1层和day层,每个相连的节点(u,v)都有一条权值为w[day]的边,表示从day-1天在u到day天到v需要w[day]的路费。这样考虑的话,我们可以把每个节点拆成k个,然后每个节点u的第day-1个连到v节点的第day个,边权为w[day],构建一个图然后跑最短路。
但是,蒟蒻不会拆点(划掉)。由于每次连点都是从u的day-1转移到v的day,因此,考虑在松弛操作上做手脚,达到类似分层的效果:把松弛操作改为

if(dis[v][day+1]>dis[u][day]+e[i].w+a[day+1]) dis[v][day+1]=dis[u][day]+e[i].w+a[day+1]

另外,需要特判一个条件:因为k天后就追不到了,因此,还需要:

if(day+1>k) continue;

不拿该状态去更新。
另:蒟蒻表示一开始并不是这么想的,没有考虑分层的问题。

错误代码

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}

template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod 
    ll ans=1;
    while(n){
        if(n&1) ans=((ans%mod)*(a%mod))%mod;
        a=((a%mod)*(a%mod))%mod;
        n>>=1;
    }
    return ans%mod;
}
//==============================================================
const int maxm=1e4+10,maxn=1e3+10;
int n,m,k;
struct Edge{
    int to,next,w;
}e[maxm<<1];
int head[maxn],cnt;
int a[maxn];
void add(int x,int y,int w){
    e[cnt].to=y;
    e[cnt].w=w;
    e[cnt].next=head[x];
    head[x]=cnt++;
}
struct node{
    int u,dis,t,cost;
    node(int uu,int dd,int tt){
        u=uu;
        dis=dd;
        t=tt;
        cost=(t>k?inf:dis+a[t]);
    }
};
auto cmp=[](const node&a,const node&b){
    return a.cost>b.cost;
};
priority_queue<node,vector<node>,decltype(cmp)> que(cmp);
int dis[maxn],vis[maxn];
int solve(){
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    que.push(node(1,0,1));
    while(!que.empty()){
        node now=que.top();que.pop();
        int u=now.u;
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].to;
            if(dis[v]>(now.t<=k?dis[u]+e[i].w+a[now.t]:inf)){
                dis[v]=dis[u]+e[i].w+a[now.t];
                if(!vis[v]) que.push(node(v,dis[v],now.t+1));
            }
        }
    }
    if(dis[n]==inf) return -1;
    else return dis[n];
}

signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    //===========================================================
    memset(head,-1,sizeof(head));
    read(n),read(m),read(k);
    rep(i,1,m){
        int x,y,c;read(x),read(y),read(c);
        add(x,y,c),add(y,x,c);
    }
    rep(i,1,k) read(a[i]);
    write(solve());
    //===========================================================
    return 0;
}

hack数据是:
6 8 2
1 2 499
2 3 499
3 4 490
1 3 1
4 6 1
1 5 1000
5 6 4999
3 5 5
0 1
原因是:因为图没有分层,所以5点被1——3——5更新完距离为6后,又被1——5路径转移过来的node更新节点6的距离,导致用的是dis[5]=6,但天数没有匹配上。因此,想到分层。

AC代码

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
//#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}

template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod 
    ll ans=1;
    while(n){
        if(n&1) ans=((ans%mod)*(a%mod))%mod;
        a=((a%mod)*(a%mod))%mod;
        n>>=1;
    }
    return ans%mod;
}
//==============================================================
//#define int ll
ll INF=inf;
const int maxm=1e4+10,maxn=1e3+10;
int n,m,k;
struct Edge{
    int to,next,w;
}e[maxm<<1];
int head[maxn],cnt;
int a[maxn];
void add(int x,int y,int w){
    e[cnt].to=y;
    e[cnt].w=w;
    e[cnt].next=head[x];
    head[x]=cnt++;
}
struct node{
    int u,dis,t;
    node(int uu,int dd,int tt){
        u=uu;
        dis=dd;
        t=tt;
    }
};
auto cmp=[](const node&a,const node&b){
    return a.dis>b.dis;
};
priority_queue<node,vector<node>,decltype(cmp)> que(cmp);
int dis[maxn][20],vis[maxn][20];
/*int solve(){
    rep(i,0,n){
        dis[i]=INF;
    }
    //memset(dis,inf,sizeof(dis));
    dis[1]=0;
    que.push(node(1,0,1));
    while(!que.empty()){
        node now=que.top();que.pop();
        int u=now.u;
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].to;
            if(dis[v]>(now.t<=k?dis[u]+e[i].w+a[now.t]:INF)){
                dis[v]=dis[u]+e[i].w+a[now.t];
                if(v==n&&dis[v]==5007){
                    cerr<<now.t<<endl;
                }
                if(!vis[v]) que.push(node(v,dis[v],now.t+1));
            }
        }
    }
    if(dis[n]==INF) return -1;
    else return dis[n];
}*/
ll solve(){
    memset(dis,inf,sizeof(dis));
    dis[1][0]=0;
    que.push(node(1,0,0));
    while(!que.empty()){
        node now=que.top();que.pop();
        int u=now.u;
        if(vis[u][now.t]) continue;
        //cerr<<"ok"<<endl;
        vis[u][now.t]=1;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].to;
            if(now.t+1>k) continue;
            if(dis[v][now.t+1]>dis[u][now.t]+e[i].w+a[now.t+1]){
                dis[v][now.t+1]=dis[u][now.t]+e[i].w+a[now.t+1];
                que.push(node(v,dis[v][now.t+1],now.t+1));
            }
        }
    }
    int ans=inf;
    rep(i,1,k){
        ans=min(ans,dis[n][i]);
    }
    if(ans==inf) return -1;
    return ans;
}

signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    //===========================================================
    memset(head,-1,sizeof(head));
    read(n),read(m),read(k);
    rep(i,1,m){
        int x,y,c;read(x),read(y),read(c);
        add(x,y,c),add(y,x,c);
    }
    rep(i,1,k) read(a[i]);
    //rep(i,1,k) a[i]+=a[i-1];
    write(solve());
    //===========================================================
    return 0;
}