• Dijkstra算法示例程序


    输入:一个有向图,顶点个数 n ,然后是每条边的起点,终点,权值。顶点序号从0开始,-1 -1 -1表示结束。

    输出:顶点0到其他各顶点的最短路径长度,并输出对应的最短路径。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 const int MAX = 20;
    23 int S[MAX], dist[MAX], path[MAX], edge[MAX][MAX];
    24 int n;
    25 void Dijkstra(int v0) {
    26   int i, j, k;
    27   for (i = 0; i < n; ++i) {
    28     dist[i] = edge[v0][i]; S[i] = 0;
    29     if (i != v0 && edge[v0][i] != MAXN) path[i] = v0;
    30     else path[i] = -1;
    31   }
    32   S[v0] = 1; dist[v0] = 0;
    33   for (i = 0; i < n-1; ++i) {
    34     int Min = MAXN, u = v0;
    35     for (j = 0; j < n;++j) {
    36       if (S[j] == 0 && dist[j] < Min) {
    37         Min = dist[j]; u = j;
    38       }
    39     }
    40     S[u] = 1;
    41     for (j = 0; j < n; ++j) {
    42       if (S[j] == 0 && edge[u][j] != MAXN) {
    43         int tmp = edge[u][j] + dist[u];
    44         if (tmp < dist[j]) {
    45           dist[j] = tmp; path[j] = u;
    46         }
    47       }
    48     }
    49   }
    50 }
    51 int main(void){
    52 #ifndef ONLINE_JUDGE
    53   freopen("dijkstra.in", "r", stdin);
    54 #endif
    55   scanf("%d",&n); 
    56   int u, v, w, i, j, k;
    57   while (1) {
    58     scanf("%d%d%d", &u, &v, &w);
    59     if (u == -1 && v == -1 && w == -1) break;
    60     edge[u][v] = w;
    61   }
    62   for (i = 0; i < n;++i) {
    63     for (j = 0; j < n; ++j) {
    64       if (i == j) edge[i][j] = 0;
    65       else if (edge[i][j] == 0) edge[i][j] = MAXN;
    66     }
    67   }
    68   Dijkstra(0);
    69   for (i = 1; i < n;++i) {
    70     printf("%d\t", dist[i]);
    71     int Shortest[MAX]; k = 0;
    72     Shortest[k] = i;
    73     while (path[Shortest[k]] != 0) {
    74       ++k; Shortest[k] = path[Shortest[k-1]];
    75     }
    76     ++k; Shortest[k] =0;
    77     for (j = k; j > 0; --j) {
    78       printf("%d->", Shortest[j]);
    79     }
    80     printf("%d\n", Shortest[0]);
    81   }
    82 
    83   return 0;
    84 }

      采用所谓的“倒向追踪”的方法记录最短路径的时候,要注意怎么存储路径。写的时候,这里出现了一个bug。

    输出路径的时候,赶脚书上的写法有点儿挫……所以自己又写了一遍。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x7fffffff;
    18 const int  MINN =  -0x7fffffff;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 const int MAX = 200;
    23 int edge[MAX][MAX], dist[MAX], path[MAX]; bool S[MAX];
    24 int n, m;
    25 void Dijkstra(int u0) {
    26   int i, j, k, u, Min;
    27   for (i = 0; i < n; ++i) {
    28     dist[i] = edge[u0][i]; S[i] = false;
    29     if (u0!=i && edge[u0][i] != MAXN) path[i] = u0;
    30     else path[i]= -1;
    31   }
    32   S[i] = true; dist[u0] = 0; path[u0] = -1;
    33   for (i = 1; i < n; ++i) {
    34     u = u0; Min = MAXN;
    35     for (j = 0; j < n; ++j) {
    36       if (S[j] == false && dist[j] < Min) {
    37         Min = dist[j]; u = j;
    38       }
    39     }
    40     S[u] = true;
    41     for (j = 0; j < n; ++j) {
    42       if (S[j] == false && edge[u][j] != MAXN) {
    43         int tmp= edge[u][j] + dist[u];
    44         if (tmp < dist[j]) {
    45           dist[j] = tmp;
    46           path[j] = u;
    47         }
    48       }
    49     }
    50   }
    51 }
    52 
    53 int main(void){
    54 #ifndef ONLINE_JUDGE
    55   freopen("dijkstra.in", "r", stdin);
    56 #endif
    57   int u, v, w;
    58   memset(edge, 0, sizeof(edge));
    59   scanf("%d", &n);
    60   while (1) {
    61     scanf("%d%d%d", &u, &v, &w);
    62     if (u == -1 && v == -1 && w == -1) break;
    63     edge[u][v] = w;
    64   }
    65   int i, j, k;
    66   for (i = 0; i < n; ++i) {
    67     for (j = 0; j < n; ++j) {
    68       if (i == j) edge[i][j] = 0;
    69       else if(edge[i][j] == 0) edge[i][j] = MAXN;
    70     }
    71   }
    72   int Path[MAX]; Dijkstra(0);
    73   for (i = 1; i < n; ++i) {
    74     printf("%d\t",dist[i]);
    75     k= 0; Path[0] = i; int ho = path[i];
    76     while (ho != -1) {
    77       Path[++k] = ho; ho = path[ho];
    78     }
    79     for (j = k; j > 0; --j) printf("%d->", Path[j]);
    80     printf("%d\n", Path[0]);
    81   }
    82 
    83   return 0;
    84 }

      因为做了两道题目,都没有要求输出路径的,所以自己还是写一下输出路径的吧。注意一下,开始标记路径的时候,把和u0相连的标记为u0,其它的不相连的标记为-1.循环结束后,把path[u0]标记为-1,表示起点。Dijkstra算法最后求得的dist[]是u0到每个点的最短距离。

      现在感觉,平时就要有意识地训练一下自己的查错能力,这样,真正比赛的时候,就不会因为找不出来错而着急了。

  • 相关阅读:
    数据仓库
    数据库事务隔离级别与锁
    并发包之Future:代码级控制超时时间
    axis2 webservice 发布、调用与项目集成
    配置远程控制
    解决局部刷新的问题
    Sharepoint 2013 搜索高级配置(Search Scope)
    重启IIS报错:IIS 服务或万维网发布服务,或者依赖这 服务可能在启动期间发生错误或者已禁用
    错误提示:此产品的试用期已经结束
    Sharepoint 2013 启用搜做服务
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3060251.html
Copyright © 2020-2023  润新知