• 最短路问题-- Dijkstra Choose the best route


    Choose the best route

    Problem Description

    One day , Kiki wants to visit one of her friends. As she is liable to carsickness , she wants to arrive at her friend’s home as soon as possible . Now give you a map of the city’s traffic route, and the stations which are near Kiki’s home so that she can take. You may suppose Kiki can change the bus at any station. Please find out the least time Kiki needs to spend. To make it easy, if the city have n bus stations ,the stations will been expressed as an integer 1,2,3…n.

    Input

    There are several test cases.
    Each case begins with three integers n, m and s,(n<1000,m<20000,1=<s<=n) n stands for the number of bus stations in this city and m stands for the number of directed ways between bus stations .(Maybe there are several ways between two bus stations .) s stands for the bus station that near Kiki’s friend’s home.
    Then follow m lines ,each line contains three integers p , q , t (0<t<=1000). means from station p to station q there is a way and it will costs t minutes .
    Then a line with an integer w(0<w<n), means the number of stations Kiki can take at the beginning. Then follows w integers stands for these stations.
     

    Output

    The output contains one line for each data set : the least time Kiki needs to spend ,if it’s impossible to find such a route ,just output “-1”.
     
    $Dijkstra$ 算法:以点为思考中心的最短路径算法。
    图结构存储:邻接表
    流程:1.初始化
    1 const int INF = 1e9; 
    2 bool hasFind[maxn]; 
    3 for (int i = 0 ;i<= n ;i++) 
    4     dist[i] = INF; 
    5 dist[sNode] = 0; 
    6 memset(hasFind,0,sizeof hasFind); 
    7 hasFind[sNode] = true;

    具体流程为:

     1 for (int i = 0 ;i< n-1 ;i++){ 
     2     int nId = -1 ; 
     3     for (int j = 0 ;j< n ;j++){ 
     4         if (!hasFind[j]){ 
     5             if (nId == -1) 
     6                 nId = j; 
     7             else if (dist[j]<dist[nId]) 
     8                 nId = j; 
     9             } 
    10         } 
    11         hasFind[nId] = true; 
    12     for (int i = 0 ;i< node[nId].size() ;i++){
    13         int nextId = node[nId][i].nextId; 
    14         if (node[nId][i].dist + dist[nId]< dist[nextId]){ 
    15             dist[nextId] = node[nId][i].dist + dist[nId]; 
    16             que.push(nextId); 
    17             }
    18     }
    19 }

     时间复杂度 节点个数 $N$,边个数 $M$ $O$($N imes N$)

     举例 • 求所有节点到节点 1 的最短距离

     

     1. 初始化
    • 将源节点 1,放入已获取最短路径集合, 集合变为 {1}

    • 未获取最短路径节点结合 {2,3,4,5}

    • 根据节点 1 来更新所有节点距离源节点的距离 $dist$

    2. 流程
    (a) $step$ 1:

    • 从未获取最短路径节点结合 {2,3,4,5} 中,选取距离源节点最 近的节点 3

    • 将节点 3,放入已获取最短路径集合, 集合变为 {1,3}

    • 根据节点 3 来更新所有节点距离源节点的距离 $dist$

     

     

     (b) $step$ 2:

    • 从未获取最短路径节点结合 {2,4,5} 中,选取距离源节点最 近的节点 2

    • 将节点 2,放入已获取最短路径集合, 集合变为 {1,2,3}

    • 根据节点 2 来更新所有节点距离源节点的距离 $dist$

     

     (c) $step$ 3:

    • 从未获取最短路径节点结合 {4,5} 中,选取距离源节点最近 的节点 4

    • 将节点 4,放入已获取最短路径集合, 集合变为 {1,2,3,4}

    • 根据节点 4 来更新所有节点距离源节点的距离 $dist$

     

     (d) $step$ 4:

    • 从未获取最短路径节点结合 {5} 中,选取距离源节点最近的 节点 5

    • 将节点 5,放入已获取最短路径集合, 集合变为 {1,2,3,4,5}

    • 根据节点 5 来更新所有节点距离源节点的距离 $dist$

     

     (e) 终止条件,所有节点都放入到了已获取最短路径集合。

    把所有部分合并在一起得到一段代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #define Inf 0x3f3f3f3f
     6  
     7 using namespace std;
     8 int map[1005][1005];
     9 int vis[1005],dis[1005];
    10 int n,m;//n个点,m条边
    11 void Init ()
    12 {
    13     memset(map,Inf,sizeof(map));
    14     for(int i=1;i<=n;i++)
    15     {
    16         map[i][i]=0;
    17     }
    18 }
    19 void Getmap()
    20 {
    21     int u,v,w;
    22     for(int t=1;t<=m;t++)
    23     {
    24           scanf("%d%d%d",&u,&v,&w);
    25           if(map[u][v]>w)
    26           {
    27           map[u][v]=w;
    28           map[v][u]=w;
    29           }
    30     }    
    31 }
    32  
    33 void Dijkstra(int u)
    34 {
    35     memset(vis,0,sizeof(vis));
    36     for(int t=1;t<=n;t++)
    37     {
    38         dis[t]=map[u][t];
    39     }
    40     vis[u]=1;
    41     for(int t=1;t<n;t++)
    42     {
    43         int minn=Inf,temp;
    44         for(int i=1;i<=n;i++)
    45         {
    46             if(!vis[i]&&dis[i]<minn)
    47             {
    48                 minn=dis[i];
    49                 temp=i;
    50             }
    51         }
    52         vis[temp]=1;
    53         for(int i=1;i<=n;i++)
    54         {
    55             if(map[temp][i]+dis[temp]<dis[i])
    56             {
    57                 dis[i]=map[temp][i]+dis[temp];
    58             }
    59         }
    60     }
    61 }
    62  
    63 int main()
    64 {
    65     
    66     scanf("%d%d",&m,&n);
    67     Init();
    68     Getmap();
    69     Dijkstra(n);
    70     printf("%d
    ",dis[1]);    
    71     return 0;
    72 }

    这道题的代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <cstdlib>
     8 using namespace std;
     9 
    10 const int INF=0x3f3f3f3f;
    11 const int N=1010;
    12 int mp[N][N];
    13 int dis[N];
    14 int vis[N];
    15 int m;
    16 int n;
    17 int dijstra()
    18 {
    19     memset(dis,0x3f,sizeof(dis));
    20     memset(vis,0,sizeof(vis));
    21     dis[0]=0;
    22     for(int i=1;i<=n;i++)
    23     {
    24         int k=0;
    25         int mini=INF;
    26         for(int j=1;j<=n;j++)
    27         {
    28             if(!vis[j]&&mini>dis[j])
    29                 mini=dis[k=j];
    30         }
    31         vis[k]=1;
    32         if(k==m) return dis[m];
    33         for(int j=1;j<=n;j++)
    34         {
    35             if(vis[j]||mp[k][j]==INF) continue;
    36             dis[j]=min(dis[j],dis[k]+mp[k][j]);
    37         }
    38     }
    39     return dis[m];
    40 }
    41 int main()
    42 {
    43     int s;         //已修好的路有几条
    44     while(~scanf("%d%d%d",&n,&s,&m))    //终点是m,最远的点是n
    45     {
    46         memset(mp,INF,sizeof(mp));
    47         while(s--)
    48         {
    49             int a,b,c;
    50             scanf("%d%d%d",&a,&b,&c);
    51             if(mp[a][b]>c)
    52                 mp[a][b]=c;
    53         }
    54         int d;      
    55         scanf("%d",&d);
    56         while(d--)
    57         {
    58             int x;      
    59             scanf("%d",&x);
    60             mp[0][x]=0;      
    61         }
    62         int k=dijstra();
    63         if(k==INF) printf("-1
    ");
    64         else printf("%d
    ",dijstra());
    65     }
    66     return 0;
    67 }

     

     

     

     
  • 相关阅读:
    HL极大算子弱(1,1)范数趋于无穷, 当维数趋于无穷
    Stein's Maximal principle
    课程: 广义相对论和波方程
    关于球乘子和BochnerRiesz乘子的相关文献
    The Hardy Uncertainty Principle
    Mar. 22 10:0011:30, 1569, "Global wellposedness for the nonlinear Schrodinger equation with derivative in energy space" by Yifei Wu
    Several questions regarding construction of functions
    通知: 强化班<调和分析与PDE>3月26日的课程 改到3月21 晚上6:009:00 地点不变
    ADO.NET Entity Framework 入门示例向导
    JavaScript 定义类方法
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12207322.html
Copyright © 2020-2023  润新知