有边数限制的最短路

该程序使用Dijkstra算法的变种,通过k次循环和每次循环内的m次更新来寻找从起点到第n个点的最短路径。在循环过程中,每次更新基于之前步数的路径距离。如果在k次循环后目标点的距离仍大于INF的一半,则认为无法到达。边的权重范围为[-10000,10000],最终输出路径距离或标记为不可能。
摘要由CSDN通过智能技术生成

 

 

整体思路就是进行k次循环然后每层循环内部进行m次循环更新距离,

因为外层循环每一次操作可以向前一步走(如果有路),如果k次循环后为INF,就说明走不到第n个点

然后是更新方面,因为我们每次第k次循环更新用的值需要第k-1次循环的dist(表示走了k次),所以我们在内层循环的开始,每次用一个memcpydist进行赋值到backup中,之后取backup的值进行更新即可

最后关于dist[n]的一个小问题

假设n4dist[3]=INF,dist[4]=INF,但是第三个点到第四个点的距离为-2,故可以更新一下,所以最后的dist[n]不一定为INF(即使他走不到n点),再看数据范围,边长不超过100001≤m≤10000,故减少的最大值也不会超过1e8,而INF1e9,最后判断是否>INF/2即可

#include<stdio.h>

#include<iostream>

#include<cmath>

#include<cstring>

using namespace std;

const int N=10000+100,INF=0x3f3f3f3f;

int dist[N],backup[N];

int n,m,k;//点,边,次数

struct lk{

  int l,r,res;

}z[N];

int bell()

{

    memset(dist,INF,sizeof dist);

    dist[1]=0;

    for(int i =1;i<=k;i++)

    {

      memcpy(backup,dist ,sizeof dist);

      for(int i =1;i<=m;i++)

      {

        dist[z[i].r]=min(backup[z[i].l]+z[i].res,dist[z[i].r])

      }

    }

}

int main()

{

  cin>>n>>m>>k;

  for(int i =1;i<=m;i++)

  cin>>z[i].l>>z[i].r>>z[i].res;

  bell();

  if(dist[n]>INF/2) cout<<"impossible\n";

  else cout<<dist[n]<<endl;

  return  0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值