Label Correcting Algorithm(Python实现)

代码:
dequeue版:

from collections import deque
import numpy as np
class edge:                       #定义边
    def __init__(self,start,end,cost):
        self.Start=start
        self.End=end
        self.Cost=cost
inf=2147483647
n=int(input("n="))                #n是点数
m=int(input("m="))                #m是边数
E=[]                              #存图中所有的边
Edge=np.zeros((n+1,n+1),dtype=int)#邻接表/前向星
dist=np.empty((n+1),dtype=int)    #记录当前最短路长度
vis=np.zeros((n+1),dtype=int)     #0表示未入队,1表示在队中,-1表示已出队
pre=np.zeros((n+1),dtype=int)     #记录前一个节点
Q=deque()
'''
def TestEdge():                   #邻接表测试函数
    for i in range(1,n+1):
        for j in range(1,Edge[i,0]+1):
            print(i,E[Edge[i,j]].End,E[Edge[i,j]].Cost)
'''
def FindTheWay(x):                #递归输出路径
    if pre[x]>0:
        FindTheWay(pre[x])
        print(pre[x],"->",end='')

for i in range(m):
    start,end,cost=map(int,input().split())  #读起点终点花费
    E.append(edge(start,end,cost))           #加入图中,存边
    Edge[start][Edge[start][0]+1]=i          #记录start节点发出一条新边
    Edge[start][0]+=1

for i in range(n+1):
    dist[i]=inf
s=int(input("起点:"))
t=int(input("终点:"))
dist[s]=0
Q.append(s)
vis[s]=1;
while len(Q)>0:
    tmp=int(Q.popleft())
    vis[tmp]=-1
    length=Edge[tmp][0]
    for i in range(1,length+1):
        index=Edge[tmp][i]
        to=E[index].End
        if dist[to]>dist[tmp]+E[index].Cost:
            dist[to]=dist[tmp]+E[index].Cost
            pre[to]=tmp
            if vis[to]==-1: Q.appendleft(to)
            else: Q.append(to)
            vis[to]=1
if dist[t]<inf:
    print("最短路长度=",dist[t])
    print("最短路径为:",end='')
    FindTheWay(t)
    print(t)
else: print("无法到达")

sequence list版:

import numpy as np
inf=2147483647
n=int(input("n="))                #n是点数
m=int(input("m="))                #m是边数
class edge:                       #定义边
    def __init__(self,start,end,cost):
        self.Start=start
        self.End=end
        self.Cost=cost
class SequenceList:                    #定义队列
    vis=np.zeros((n+1),dtype=int)
    def __init__(self):
        self.right=int(0)
        self.vis[0]=inf
    def AddToQ(self,x):                #加入队尾
        self.vis[self.right]=x
        self.vis[x]=inf
        self.right=x
    def AddToQLeft(self,x):            #加入队首
        self.vis[x]=self.vis[0]
        self.vis[0]=x
    def pop(self):                     #取队首元素
        tmp=self.vis[0]
        self.vis[0]=self.vis[tmp]
        self.vis[tmp]=-1
        if tmp==self.right: self.right=0
        return tmp
    def empty(self):                   #判断队列是否为空
        if self.vis[0]==inf: return 1  #队列为空,返回真(1)
        else: return 0                 #队列非空,返回假(0)

E=[]                              #存图中所有的边
Q=SequenceList()                  #SequenceList实例化
Edge=np.zeros((n+1,n+1),dtype=int)#邻接表/前向星
dist=np.empty((n+1),dtype=int)    #记录当前最短路长度
pre=np.zeros((n+1),dtype=int)     #记录前一个节点

def FindTheWay(x):                #递归输出路径
    if pre[x]>0:
        FindTheWay(pre[x])
        print(pre[x],"->",end='')

for i in range(m):
    start,end,cost=map(int,input().split())  #读起点终点花费
    E.append(edge(start,end,cost))           #加入图中,存边
    Edge[start][Edge[start][0]+1]=i          #记录start节点发出一条新边
    Edge[start][0]+=1

for i in range(n+1):
    dist[i]=inf
s=int(input("起点:"))
t=int(input("终点:"))
dist[s]=0
Q.AddToQ(s)
while Q.empty()==0:
    tmp=Q.pop()
    length=Edge[tmp][0]
    for i in range(1,length+1):
        index=Edge[tmp][i]
        to=E[index].End
        if dist[to]>dist[tmp]+E[index].Cost:
            dist[to]=dist[tmp]+E[index].Cost
            pre[to]=tmp
            if Q.vis[to]==-1: Q.AddToQLeft(to)
            else: Q.AddToQ(to)
if dist[t]<inf:
    print("最短路长度=",dist[t])
    print("最短路径为:",end='')
    FindTheWay(t)
    print(t)
else: print("无法到达")

样例:
这里写图片描述

输入:
n=4

m=4

1 2 1

2 3 2

2 4 10

3 4 5

起点:1

终点:4


输出:
最短路长度= 8
最短路径为:1 ->2 ->3 ->4
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值