最短路径

1.Floyd-Warshall算法  多源最短路径

算法思想:通过比较通过其他1,2,条边到达终点的距离来更新

用邻接矩阵存储后:

核心代码:

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

{

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

for(int j=1;j<=n;j++)

{

   if(a[i][j]>a[i][k]+a[k][j])

      a[i][j]=a[i][k]+a[k][j];

}

}

 

2.Dijkstra算法 单源最短路(无法解决负权边)

需要一个辅助数组dis来存储起点到其他所有点的距离

将dis数组中的值称为最短路程的"估计值"

核心思想:通过边来松弛起点到其他各个点的距离

代码;

//初始化dis数组

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

  dis[i]=a[1][i](假设起点为1)

//标记数组初始化visted

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

   visted[i]=0;

 visted[1]=1;

//接下来重复过程

在dis数组中找当前离起点最近的点

然后访问这个点的所有边看是否能通过dis数组更新起点到那些边的距离

能的话就更新

代码:(部分是伪代码)

 int min=Inf;

 for(int i=1;i<=dis.size();i++)

  {

    if(dis[i]<min)

     {

        min=dis[i];

        mark=i  ;//mark用来记录这一点

     }

}

然后更新:

 for(int v=1;v<=n;v++)

   {

      if(a[mark][v]<inf)

        {

             if(dis[v]>dis[mark]+a[mark][v])

                dis[v]=dis[mark]+a[mark][v];

        }

   }

 

这个过程持续n-1所以最外层还要加上循环

 for(int k=1;k<=n-1;k++)

{

 ….

}

 

时间复杂度O(n^2)

 

3.Bellman-Ford算法-解决负权边

有dis数组  对所有边进行n-1次松弛操作

核心代码:

for(k=1;k<=n-1;k++)

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

   if(dis[v[i]]>dis[u[i]]+w[i])

     dis[v[i]]=dis[u[i]]+w[i];

O(NM)

可以用check标记检测若dis数组已经不再更新就跳出循环

 

问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式

共n-1行,第i行表示1号点到i+1号点的最短路。

样例输入

3 3

1 2 -1

2 3 -1

3 1 2

样例输出

-1

-2

数据规模与约定

对于10%的数据,n = 2,m = 2。

对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点

 

来自 <http://lx.lanqiao.cn/problem.page?gpid=T15>

#include<iostream>

using namespace std;

const int Inf=99999999;

const int maxn=200010;

int u[maxn],v[maxn],w[maxn];

int main() {

int n,m;

while(cin>>n>>m) {

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

cin>>u[i]>>v[i]>>w[i];

int *dis=new int [n+1];

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

dis[i]=Inf;

dis[1]=0;

int check;

for(int i=1; i<=n-1; i++) {

check=0;

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

if(dis[v[j]]>dis[u[j]]+w[j])

{

dis[v[j]]=dis[u[j]]+w[j];

check=1;

}

if(check==0)

break;        

}

for(int i=2; i<=n; i++)

cout<<dis[i]<<endl;

}

return 0;

}

 

 

原文地址:https://www.cnblogs.com/wtblogwt/p/10585076.html