最短路
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3
2
这里需要注意,由于是多组输入,每次min都应该重新赋值成无穷(INF),否则会出现错误。
C语言:
#include<stdio.h>
#define INF 0x3f3f3f3f
int N,M; //有N个结点,M条路
int A,B,C;
int a[111][111]; //存放输入的数据 .a[x][y]=z 代表x→y需要花费的时间为z
int dis[111]; // 存放x的最短路径.dis[x]=z 代表 1→x需要花费的最短时间为z
int bj[111]; //判断x是否已经是永久标号了.bj[x]=1 代表已经是永久标号了,bj[x]=0则不是
void dijkstra(int n) //自定义dijkstra函数,求起点1到各点的最短时间(路径)
{
for(int u=1;u<=n;u++)
{
int k=1;
for(int i=1;i<=n;i++)
{
int min=INF;
for(int j=1;j<=n;j++)
{
if(bj[j]==0 && dis[j]<min) //从不是永久标号的点中,寻找所需时间最短的结点
{
min=dis[j];
k=j;
}
}
bj[k]=1; //将找到的时间最短的结点变成永久标号
for(int j=1;j<=n;j++)
{
if(bj[j]==0 && (dis[k]+a[k][j])<dis[j]) //更新最短时间变化但并不是此时找到的最短时间的结点
{
dis[j]=dis[k]+a[k][j];
}
}
}
}
}
int main()
{
while(~scanf("%d%d",&N,&M))
{
if(N==0 && M==0) break;
/*↓↓↓初始化↓↓↓*/
for(int i=1;i<=N;i++)
{
for(int j=1;j<=N;j++)
{
if(i==j) a[i][j]=0; //i与j相同时,i→j花费的时间为0
else a[i][j]=INF; //i与j不同时,i→j没有路,花费的时间为无穷
}
}
/*↓↓↓接收数据↓↓↓*/
for(int i=1;i<=M;i++)
{
scanf("%d%d%d",&A,&B,&C);
a[A][B]=a[B][A]=C; //无向图,A→B和B→A要花费的时间均为C
}
/*↓↓↓初始化↓↓↓*/
for(int i=1;i<=N;i++)
{
dis[i]=a[1][i]; //由于起点在1,一开始i的最短时间为1→i 所需的时间,若1→i没有路则为无穷
bj[i]=0; // 刚开始各点都不是永久标号
}
bj[1]=1; // 起点为1,因此1先成为永久标号
/*↓↓↓调用函数↓↓↓*/
dijkstra(N);
/*↓↓↓输出结果↓↓↓*/
printf("%d\n",dis[N]);
}
}
python:
# -*- coding: utf-8 -*-
"""
Created on Mon May 18 00:38:53 2020
@author: 一脸呆滞
"""
INF=20000
def dijkstra(n,a,dis,bj): #自定义dijkstra函数,求起点1到各点的最短时间(路径)
for u in range(1,n+1):
k=1
for i in range(1,n+1):
Min=INF
for j in range(1,n+1):
if(bj[j]==0 and dis[j]<Min): #从不是永久标号的点中,寻找所需时间最短的结点
Min=dis[j]
k=j
bj[k]=1 #将找到的时间最短的结点变成永久标号
for j in range(1,n+1):
if(bj[j]==0 and (dis[k]+a[k][j])<dis[j]): #更新最短时间变化但并不是此时找到的最短时间的结点
dis[j]=dis[k]+a[k][j]
def solve():
N,M=map(int,input().split()) #有N个路口,共M条路
if(N==0 and M==0): #当输入两个0时结束循环
return False
#初始化
a=[[0 for i in range(N+1)] for i in range(N+1)]
dis=[[0 for i in range(N+1)] for i in range(N+1)]
bj=[[0 for i in range(N+1)] for i in range(N+1)]
for i in range(1,N+1):
for j in range(1,N+1):
if(i==j):
a[i][j]=0 #i与j相同时,i→j花费的时间为0
else:
a[i][j]=INF #i与j不同时,i→j没有路,花费的时间为无穷
#接收数据
for i in range(1,M+1):
A,B,C=map(int,input().split())
a[A][B]=a[B][A]=C #无向图,A→B和B→A要花费的时间均为C
#初始化
for i in range(1,N+1):
dis[i]=a[1][i] #由于起点在1,一开始i的最短时间为1→i 所需的时间,若1→i没有路则为无穷
bj[i]=0 #刚开始各点都不是永久标号
#调用函数
dijkstra(N,a,dis,bj)
#输出结果
print(dis[N])
return True
while(solve()): #while循环,直到solve返回False才结束循环
1
4万+

被折叠的 条评论
为什么被折叠?



