``①bellman_ford算法用于求经过k条边的最短路径
②思路是:外面一个k循环限制边数,内部一个m循环更新每个边的距离值
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510, M = 1e4 + 10;
int n, m, k;
int backup[N], dis[N];//backup数组用来储存dis的上一个状态,防止发生串联(用2更新3最短,但超出了边数限制)
struct Edge{
int a, b, w;
}edge[M];///利用结构体储存每个边路的信息(起点、终点、距离)
int bellman_ford(){
memset(dis, 0x3f, sizeof(dis));//初始化dis的值
dis[1] = 0;//初始化初始点的距离值
for(int i = 0; i < k; i ++ ){//循环k次,每次确定最短路径树上的一层点的距离值
memcpy(backup, dis, sizeof(dis));//把上次更新完的dis值储存进backup中
for(int j = 1; j <= m; j ++ ){
int a = edge[j].a, b = edge[j].b, w = edge[j].w;
dis[b] = min(dis[b], backup[a] + w);//比较b点到初始点的距离值和a点到初始点的距离值+a点到b点的距离之和,取较小值赋值给b
}
}
if(dis[n] > 0x3f3f3f3f / 2) return -1;//条件成立,代表存在和n相连的用于更新n点的点没有和初始点相连的点,但这个点已经改变了n点的值,所以n可能!=0x3f3f3f3f
return dis[n];
}
int main()
{
cin>>n>>m>>k;
for(int i = 1; i <= m; i ++ ){
cin>>edge[i].a>>edge[i].b>>edge[i].w;
}
int t = bellman_ford();
if(t == -1){
cout<<"impossible"<<endl;
}
else{
cout<<t<<endl;
}
return 0;
}
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510, M = 1e4 + 10;
struct edge{
int a, b, w;
}edg[M];
int n, m, k;
int dis[N], backup[N];
void bellman_ford(){
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
for(int i = 0; i < k; i ++ ){
memcpy(backup, dis, sizeof(dis));
for(int j = 0; j < m; j ++ )
{
auto e = edg[j];
dis[e.b] = min(dis[e.b], backup[e.a] + e.w);
}
}
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
cin>>n>>m>>k;
for(int i = 0; i < m; i ++ ){
int a, b, c;
cin>>a>>b>>c;
edg[i] = {a, b, c};
}
bellman_ford();
if(dis[n] > 0x3f3f3f3f / 2) cout<<"impossible"<<endl;
else cout<<dis[n]<<endl;
return 0;
}