zoukankan      html  css  js  c++  java
  • 3最短路的几种解法 ------例题< 最短路 >

    点击进入例题   最短路     

    我知道的有三种方法 1 : 深搜 每次  每次有更小的路径时  就更新   ,   2 :   Dijkstra    3 : floyd  

    前两种   是  单源 最短路径    ,     如果是 求 单源最短路径的话  就用前面的 两种   ,   但是 如果求的是 多源最短路径的话 最好是还用  floyd   时间复杂度 相对较低    .  用floyd 求单源最短路径的话 ....   时间复杂度 搞那么一点点 不过 程序实现简单 , 

    1 : floyd 的 实现方法 

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<set>
    #include<stack>
    #include<string>
    #include<sstream>
    #include<map>
    #include<cctype>
    using namespace std;
    #define INF 99999999
    int main()
    {
        int e[101][101];
        int n,m,a,b,c,i,j,k;
        while(~scanf("%d %d",&n,&m)&&n!=0&&m!=0)
        {
            for(i=1;i<=n;i++)      //     将  各个边  初始化 为 最大值  
                for(j=1;j<=n;j++)
                    e[i][j]=INF;
                while(m--)
                {
                    scanf("%d%d%d",&a,&b,&c);     //         确定边  和  边长 
                    e[b][a]=e[a][b]=c;  
                }
                for(k=1;k<=n;k++)    //Floyd核心算法...
                {             
                    for(i=1;i<=n;i++)       //  所有的 路 都让   k  加进去试试  
                    {
                        for(j=1;j<=n;j++)      //如果  从  i到j的路上 有k 走的会更轻松的话 , 那就让 k 去吧 
                        {
                            if(e[i][j]>e[i][k]+e[k][j])      //   判断 是否会 更加轻松       
                                e[i][j]=e[i][k]+e[k][j];
                        }
                    }
                }
                
                printf("%d
    ",e[1][n]);
        }
    }

    2 : 深搜完成   .    ( 超时 ..... 数据处理应该是没有问题的   )  

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<vector>
     8 #include<set>
     9 #include<stack>
    10 #include<string>
    11 #include<sstream>
    12 #include<map>
    13 #include<cctype>
    14 using namespace std;
    15 #define INF 99999999
    16 int n,m,a[105][105],result;
    17 vector<int>v[105];
    18 void DFS(int star,int dis)
    19 {
    20     if(dis>=result)
    21         return;
    22     if(star==n)
    23     {
    24         result=result>dis?dis:result;
    25         return ;
    26     }
    27     for(int i=0;i<v[star].size();i++)
    28     {
    29         if(a[star][v[star][i]]!=INF)
    30         {
    31             int w=a[star][v[star][i]];
    32             a[star][v[star][i]]=INF;
    33             a[v[star][i]][star]=INF;
    34             DFS(v[star][i],w+dis);
    35             a[star][v[star][i]]=w;
    36             a[v[star][i]][star]=w;
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     for(int i=0;i<105;i++)
    43         for(int j=0;j<105;j++)
    44         a[i][j]=INF;
    45     while(scanf("%d%d",&n,&m),(m||m))
    46     {
    47         result=INF;
    48         for(int i=0;i<m;i++)
    49         {
    50             int d,b,c;
    51             scanf("%d%d%d",&d,&b,&c);
    52             v[d].push_back(b);
    53             v[b].push_back(d);
    54             a[d][b]=c;
    55             a[b][d]=c;
    56         }
    57         DFS(1,0);  //  从  1  到  n .
    58         printf("%d
    ",result);
    59     }
    60 }

     3 : Dijkstra   ( 也就这一个比较有意思一点  )   < 归根结底 所有的算法 都是 模拟  ... >

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 using namespace std;
     5 #define N 0x1f1f1f1f
     6 int w[151][151];
     7 int d[155];
     8 int ans,vis[151];
     9 int n,m;
    10 void Dij()     //  Dijkstra 
    11 {
    12     int i,j,k,v,tmp;
    13     memset(vis,0,sizeof(vis));
    14     for(i=1;i<=n;i++)               //  图 中 每个节点 和  1  的距离  不是直接相邻的 就是   正无穷  
    15         d[i]=w[1][i];
    16     d[1]=0;
    17     vis[1]=1;
    18     for(i=1;i<=n;i++)
    19     {
    20         tmp=N;
    21         for(j=1;j<=n;j++)
    22         {
    23             if(tmp>d[j]&&!vis[j])      //  从中 找到一个  和  1 最近的点      (   这就是 怪姥姥讲的 已经有的 确定集合了吧    )
    24             {
    25                 tmp=d[j];
    26                 v=j;          // 记录下来 那一个端点的 标号  
    27             }
    28         }
    29         vis[v]=1;               //  最短的 端点 假如集合   ,   标记为  已经在  集合以内   
    30         for(k=1;k<=n;k++)  
    31         {
    32             if(!vis[k])         //      将所有  集合之外 但是  和 集合之中 最少一个元素相连的元素 的长度  算一下 
    33             d[k]=min(d[k],d[v]+w[v][k]);  // 但是  不让他们加进去  一会 在上面 检查一个最小的 假如已经确定长度的  集合之中  
    34         }
    35     }
    36 }
    37 int main()
    38 {
    39     printf("%d",N);
    40     while(~scanf("%d%d",&n,&m))
    41     {
    42         if(n==0&&m==0)break;
    43         for(int i=1;i<=n;i++)
    44         {
    45             for(int j=1;j<=n;j++)
    46             {
    47                 w[i][j]=0x1f1f1f1f;
    48             }
    49         }
    50         for(int i=0;i<m;i++)
    51         {
    52             int a,b,dis;
    53             scanf("%d%d%d",&a,&b,&dis);
    54             if(w[a][b]>dis)
    55             w[a][b]=w[b][a]=dis;
    56         }
    57         Dij();
    58         printf("%d
    ",d[n]);
    59     }
    60 }

     

     

  • 相关阅读:
    Java 中的打印流
    Java 转换流的简单理解
    Java IO流之缓冲流(深入浅出学习)
    Java 中与IO流有关的集合(Properties集合)
    Java IO字符流
    Objective-C 中如何测量代码的效率
    android studio 转为eclipse快捷键后还存在的问题汇总
    Mac 下安装运行Rocket.chat
    Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法
    Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
  • 原文地址:https://www.cnblogs.com/A-FM/p/5373849.html
Copyright © 2011-2022 走看看