您的位置:首页 > 其它

初学最短路算法

2016-01-31 16:44 316 查看
这几天自学了最短路的

Bellman_Ford和Dijkstra算法,通过一道简单题来回顾一下。

题目来源HDU1874.

[align=left]Problem Description[/align]
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。

现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
 

[align=left]Input[/align]
本题目包含多组数据,请处理到文件结束。

每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。

接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。

再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
 

[align=left]Output[/align]
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.

 

[align=left]Sample Input[/align]

3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2

 

[align=left]Sample Output[/align]

2
-1解一:Dijkstra算法#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define mem(a) memset(a, 0, sizeof(a))
#define eps 1e-5
#define M 100005
#define INF 99999
using namespace std;
int
vis[10006];
int
a,b;
int
d[M],w[1005][1005];//d记录从起点到I的最短距离,w[I][j]表示i到j的距离//
int
st,en;
void
Dij()
{
int
v;
for(int
i=0;i<a;i++)
{

d[i]=w[st][i];//记录di//
}

d[st]=0;//起点到起点的距离为0//
vis[st]=1;//标记起点//
for(int
i=0;i<a;i++)////循环每个点//
{
int
tmp=INF;
for(int
j=0;j<a;j++)//找到离这个点最近且没被访问的点//
{
if(
tmp>d[j]&&!vis[j])
{

tmp=d[j];
v=j;
}
}

vis[v]=1//标记这个点//
for(int
k=0;k<a;k++)
{
if(!
vis[k])
{

d[k]=min(d[k],d[v]+w[v][k]);//比较从起点直接到k点和起点经过v点到k点的大小//
}
}
}
}
int main()
{
while(
cin>>a>>b)
{

mem(vis);
mem(d);
mem(w);
for(int
i=0;i<202;i++)
{
for(int
j=0;j<202;j++)
{

w[i][j]=INF;//首先不知道I到J的距离,将其视为无穷大,后面,没有i到j的直达路线的话,也是无穷大//
w[i][i]=0;
}
}
for(int
i=0;i<b;i++)
{
int
aa,bb,cc;
cin>>aa>>bb>>cc;
if(
w[aa][bb]>cc)
{

w[aa][bb]=cc;//正确记录i到j的距离//
w[bb][aa]=cc;
}
}

cin>>st>>en;
Dij();
if(
d[en]<INF)
{

cout<<d[en]<<endl;
}
else
{

cout<<"-1"<<endl;
}
}
}
解二:Bellman_Ford算法#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define mem(a) memset(a, 0, sizeof(a))
#define eps 1e-5
#define M 100005
#define INF 0x3f3f3f3f
using namespace std;
struct
node
{
int
a,b,c;
}
d[2000];
int
aa,bb,st,en;
int
dis[M];
void
BF(int x,int y)
{
for(int
i=0;i<aa;i++)
{

dis[i]=INF;//起点到i点的距离是无穷大//
}

dis[st]=0;
for(int
i=0;i<aa-1;i++)//循环aa-1个点//
{
for(int
j=0;j<2*bb;j++)
{
if(
dis[d[j].b]>dis[d[j].a]+d[j].c)//判断从起点到b和起点经过a点到b点大小//
{

dis[d[j].b]=dis[d[j].a]+d[j].c;
}
}
}
if(
dis[en]==INF)
{

cout<<"-1"<<endl;
}
else
{

cout<<dis[en]<<endl;
}
}
int main()
{
while(
cin>>aa>>bb)
{
int
w,e,r;
for(int
i=0;i<bb;i++)
{

cin>>w>>e>>r;
d[i].a=w;
d[i].b=e;
d[i].c=r;
d[i+bb].a=e;
d[i+bb].b=w;
d[i+bb].c=r;
}

cin>>st>>en;
BF(st,en);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: