1. 程式人生 > 實用技巧 >acwing853. 有邊數限制的最短路(Bellman-Ford)

acwing853. 有邊數限制的最短路(Bellman-Ford)

給定一個n個點m條邊的有向圖,圖中可能存在重邊和自環, 邊權可能為負數

請你求出從1號點到n號點的最多經過k條邊的最短距離,如果無法從1號點走到n號點,輸出impossible。

注意:圖中可能 存在負權迴路

輸入格式

第一行包含三個整數n,m,k。

接下來m行,每行包含三個整數x,y,z,表示存在一條從點x到點y的有向邊,邊長為z。

輸出格式

輸出一個整數,表示從1號點到n號點的最多經過k條邊的最短距離。

如果不存在滿足條件的路徑,則輸出“impossible”。

資料範圍

1n,k5001≤n,k≤500,
1m100001≤m≤10000,
任意邊長的絕對值不超過10000。

輸入樣例:

3 3 1
1 2 1
2 3 1
1 3 3

輸出樣例:

3

分析:這道題是Bellman-Ford演算法限制邊數的模板題
程式碼實現:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=510,M=1e4+10;
int n,m,k;
int d[N],backup[N];
struct node{
    int x,y,w;
}s[M];
int bellan_ford()
{
    memset(d,0x3f,sizeof d);
    d[1]=0;
    for(int i=0;i<k;i++)
    {
        memcpy(backup,d,sizeof d);//儲存上一步結果,防止步數串聯
        for(int j=0;j<m;j++)
            d[s[j].y]=min(d[s[j].y],backup[s[j].x]+s[j].w);//鬆弛
    }
    if(d[n]>0x3f3f3f3f/2) return -1;
    return d[n];
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].w);
    }
    int k=bellan_ford();
    if(k==-1) printf("impossible\n");
    else printf("%d\n",k);
    return 0;
}