https://ac.nowcoder.com/acm/problem/14700
给最短路的dist数组加一维,表示现在是第几天(已经进过了几条边)
把最短路松弛操作改为:if (dist[x][k+1] > dist[y][k] + w[x][y]) dist[x][k+1] = dist[y][k] + w[x][y];即可。
或者直接拆点——一个点拆成十个重新连边即可。
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int n,m,k,u,v,w;
int a[25],vis[25][1005],dis[25][1005];
struct edge
{
int v,w;
edge(int v,int w):v(v),w(w){}
};
vector<edge>G[1005];
struct node//相当于原来的dis数组,只不过用结构体来表示了
{
int u,day;
//node(){}
node(int u,int day):u(u),day(day){}
};
void init(){
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
}
void dijstra()
{
init();
dis[0][1]=0;
queue<node> q;
q.push(node(1,0));
vis[0][1]=1;
while(!q.empty())
{
node ss=q.front();
q.pop();
vis[ss.day][ss.u]=0;
int u=ss.u;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i].v;
int w=G[u][i].w;
if(ss.day+1<=k&&dis[ss.day+1][v]>dis[ss.day][u]+a[ss.day+1]+w)//最短路的松弛操作
{
dis[ss.day+1][v]=dis[ss.day][u]+a[ss.day+1]+w;
if(!vis[ss.day+1][v]) //没有遍历过
{
q.push(node(v,ss.day+1));
vis[ss.day+1][v]=1;
}
}
}
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
G[u].push_back(edge(v,w));
G[v].push_back(edge(u,w));
}
for(int i=1;i<=k;i++)
cin>>a[i];
dijstra();
int ans=inf;
for(int i=0;i<=k;i++)
ans=min(ans,dis[i][n]);
printf("%d\n", ans == inf ? -1 : ans);
return 0;
}
/*
3 3 2
1 3 10
1 2 2
2 3 2
3 7
*/