Acwing 有边数限制的最短路(Bellman_ford算法)

地址:https://www.acwing.com/problem/content/855/

 

解析:

图里含有负权边,所以考虑Bellman_ford算法。

Bellman_ford就是从局部扩展到全局,得的是局部最优解,与Dijkstra有着很大不同。

本题要求最多经过k条边到n点的最短距离,那么引入back[]数组,用来记录上一次dis[]的状态。

对于样例一:在第一次的Bellman_ford中,2->3是不应该被更新的,只能更新1->3,这里就体现了back[]数组的作用。具体的建议手推几遍。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
int u[maxn],v[maxn],w[maxn];
int dis[maxn],back[maxn];
int n,k,m;
int bellman_ford()
{
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    for(int i=1;i<=k;i++)
    {
        memcpy(back,dis,sizeof(dis));
        for(int i=1;i<=m;i++)
        {
            dis[v[i]]=min(dis[v[i]],back[u[i]]+w[i]);
        }
    }
    if(dis[n]>inf/2)
        return -1;
    return dis[n];
}
int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++)
    {
        cin>>u[i]>>v[i]>>w[i];    
    }
    int t=bellman_ford();
    if(t==-1)
        cout<<"impossible"<<endl;
    else
        cout<<t<<endl;
}

 

posted @ 2020-11-23 16:46  liyexin  阅读(148)  评论(0编辑  收藏  举报