• wenbao与最短路(Floyd)


     Floyd算法堪称经典。仅仅五行代码就可以求出多源最短路,建议好好思考为什么可以这样求

    注意点:中转点k在最外层循环,这样可以确保【i】【k】,【k】【j】最小 

    1 for k = 1 .. N
    2     for i = 1 .. N 
    3         for j = 1 .. N
    4             若i, j, k各不相同
    5                 MinDistance[i, j] = min{MinDistance[i, j], MinDistance[i, k] + MinDistance[k, j]}
    1 for(int k=1; k<=n; k++)               //Floyd求任两点之间的最短路径
    2     for(int i=1; i<=n; i++)
    3         for(int j=1; j<=n; j++)
    4             a[i][j] = min(a[i][j], a[i][k] + a[k][j]);

     膜拜大神:

    1 for (k = 1; k <= n; ++k)    for (j = 2; j <= n; ++j){
    2   edge[j][j] = 0;
    3   for (i = 1; i < j; ++i)    if (k != i && k != j){
    4    value = edge[i][k] + edge[k][j];
    5    edge[j][i] = edge[i][j] = (edge[i][j] > value ? value : edge[i][j]);
    6     }
    7}

    矩阵对角优化,下三角,不存在路径优化,数学函数优化

     1 void floyd() {
     2     for (int k = 1; k <= n; k++) {
     3         for (int i = 1; i <= n; i++) {
     4             if (k != i) {
     5                 const int a_ki = (k < i) ? a[i][k] : a[k][i];
     6                 // skip if no path
     7                 if (a_ki == INF) continue;
     8                 const int tt = (k < i) ? k : i;
     9                 for (int j = 0; j < tt; j++) {
    10                     const int s_kj = a_ki + a[k][j];
    11                     if( s_kj < a[i][j] ) a[i][j] = s_kj;
    12                 }
    13                 for (int j = k + 1; j < i; j++) {
    14                     const int s_jk = a_ki + a[j][k];
    15                     if( s_jk < a[i][j] ) a[i][j] = s_jk;
    16                 }
    17             }
    18         }
    19     }
    20 }

    --------------------------------------------------------------

    http://hihocoder.com/problemset/problem/1089

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 using namespace std;
     5 #define INF 123456789
     6 long long a[1005][1005];       //任意两点间的最短路径长度
     7 
     8 int main(){
     9 //  freopen("in.txt","r", stdin);
    10     int n, m, x, y, t;
    11     while(scanf("%d%d", &n, &m)!=EOF){
    12         for(int i=1; i<=m; i++)
    13             for(int j=1; j<=n; j++){
    14                 a[i][j] = INF;
    15                 if(i == j) a[i][j] = 0;
    16             }
    17         for(int i=1; i<=m; i++){
    18             scanf("%d%d%d", &x, &y, &t);
    19             if(a[x][y] > t)  a[x][y] = a[y][x] = t;
    20         }
    21 
    22         for(int k=1; k<=n; k++)               //Floyd求任两点之间的最短路径
    23             for(int i=1; i<=n; i++)
    24                 for(int j=1; j<=n; j++)
    25                     a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
    26 
    27 
    28         for(int i=1; i<=n; i++){
    29             for(int j=1; j<=n; j++){
    30                 if(j>1) printf(" ");
    31                 printf("%lld", a[i][j]);
    32             }
    33             printf("
    ");
    34         }
    35     }
    36     return 0;
    37 }

    大神代码

     1 #include <stdio.h>
     2 #include <string.h>
     3 int edge[101][101];
     4 int main()
     5 {
     6     int m, n, from, to, value, i, j, k;
     7     scanf("%d%d", &n, &m);
     8     memset(edge, 0x3f, 101 * 101 * sizeof(int));
     9     for (i = 0; i < m; ++i)
    10     {
    11         scanf("%d%d%d", &from, &to, &value);
    12         if (edge[from][to] > value)
    13             edge[from][to] = edge[to][from] = value;
    14     }
    15     for (k = 1; k <= n; ++k)
    16         for (j = 2; j <= n; ++j)
    17         {
    18             edge[j][j] = 0;
    19             for (i = 1; i < j; ++i)
    20                 if (k != i && k != j)
    21                 {
    22                     value = edge[i][k] + edge[k][j];
    23                     edge[j][i] = edge[i][j] = (edge[i][j] > value ? value : edge[i][j]);
    24                 }
    25         }
    26     edge[1][1] = 0;
    27     for (i = 1; i <= n; ++i)
    28     {
    29         for (j = 1; j < n; ++j)
    30             printf("%d ", edge[i][j]);
    31         printf("%d
    ", edge[i][j]);
    32     }
    33     return 0;
    34 }
     1 #include "iostream"
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 const int maxn = 111;
     6 int a[maxn][maxn], n, m, x, y, z;
     7 #define INF 1e9
     8 
     9 void floyd() {
    10     for (int k = 1; k <= n; k++) {
    11         for (int i = 1; i <= n; i++) {
    12             if (k != i) {
    13                 const int a_ki = (k < i) ? a[i][k] : a[k][i];
    14                 // skip if no path
    15                 if (a_ki == INF) continue;
    16                 const int tt = (k < i) ? k : i;
    17                 for (int j = 0; j < tt; j++) {
    18                     const int s_kj = a_ki + a[k][j];
    19                     if( s_kj < a[i][j] ) a[i][j] = s_kj;
    20                 }
    21                 for (int j = k + 1; j < i; j++) {
    22                     const int s_jk = a_ki + a[j][k];
    23                     if( s_jk < a[i][j] ) a[i][j] = s_jk;
    24                 }
    25             }
    26         }
    27     }
    28 }
    29 
    30 int main() {
    31 #ifdef wenbao
    32     freopen("in", "r", stdin);
    33 #endif
    34     scanf("%d%d", &n, &m);
    35     for(int i = 1; i <= n; ++i){
    36         for(int j = 1; j < i; ++j){
    37             a[i][j] = a[j][i] = INF;
    38         }
    39     }
    40     for(int i = 0; i < m; ++i){
    41         scanf("%d%d%d", &x, &y, &z);
    42         if(z < a[x][y]) a[x][y] = a[y][x] = z;
    43     }
    44     floyd();
    45     for(int i = 1; i <= n; ++i){
    46         for(int j = 1; j <= n; ++j){
    47             printf("%d%c", i >= j ? a[i][j]: a[j][i],  " 
    "[j == n]);
    48         }
    49     }
    50     return 0;
    51 }

    --------------------------------------------------------------------

    只有不断学习才能进步!

  • 相关阅读:
    几种参数传递问题(读c++ primer plus)
    开源技术知识
    指针、引用与句柄(综合别人博客,方便大家和自己学习)
    转OpenGLhttp://www.zwqxin.com/archives/opengl.html
    我电脑上安装的软件(XP系统,GIS专业)
    回忆照片
    Richfaces为何那么“慢”?
    Windows和Linux下Java程序开发入门
    MiniOA项目介绍及源代码下载(Java JSF B/S)
    年会抽奖程序代码讲解(c#版)
  • 原文地址:https://www.cnblogs.com/wenbao/p/5896243.html
Copyright © 2020-2023  润新知