zoukankan      html  css  js  c++  java
  • 最短路径

    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;

    }

     

     

  • 相关阅读:
    java课后思考问题(二)
    论文-MS-CNN
    论文-ION--Inside-Outside Net: Detecting Objects in Context with Skip
    51Nod--1285-山峰和分段
    论文-Learning Features and Parts for Fine-Grained Recognition
    论文-Multi-view Convolutional Neural Networks for 3D Shape Recognition
    论文-SPP_net
    Leetcode 448. Find All Numbers Disappeared in an Array
    FlowNet
    LeetCode Weekly Contest 21
  • 原文地址:https://www.cnblogs.com/wtblogwt/p/10585076.html
Copyright © 2011-2022 走看看