[Summary] graph theory algorithms - shortest path

[Summary] graph theory algorithms - shortest path

First, the concept

The shortest path problem. I.e., to find the path length between two specific nodes in a shortest FIG. FIG called path, i.e., a starting point to the node from the graph way a sequence of all nodes through which the end node, the right side, i.e., the path length and elapsed. 

Two, Floyd algorithm

Save original adjacency matrix, then the time adjacency matrix edge [i] [j] indicates a value that is from node i to node j, the minimum value without any intermediate node distance (if there therebetween a plurality of sides, takes the minimum value stored to the adjacency matrix weight; may be infinite, i.e. unreachable). Suppose the node numbered 1 to N, we consider from node i to node j shortest path length through only the intermediate node number is less than equal to 1 (or may not go through) . Compared with the original condition, on the intermediate node through the path it may increase the number of nodes 1. We also know that the node on the shortest path will not duplicate (without regard to the presence of negative weights). Then, if the two nodes between a node 1 and allowed to pass through the emergence of new shortest path because the path is node 1 is divided into two parts: from the node i to 1, while does not pass through the intermediate nodes on the path path is the first section 1; 1 to the node j, not the same path through the intermediate node on the path a second segment, which is the total path length of edge [i] [1] + edge [1] [j]. To determine whether the path through the node is not allowed is shorter than 1, we compare edge [i] [1] + edge [1] [j] magnitude relation between edge [i] [j] with . If the former is smaller, then the intermediate node through the path 1 is shorter than the original, with the value represented by the i to j path intermediate node number equal to the shortest path length is less than 1; otherwise, the path length will remain the original values edge [i] [j], i.e., allowed to pass though the node 1, but the length is not the shortest path passes

Consider a more general case, if the edge [i] [j] represents from node i to node j, only through the middle of the shortest path length is less than the number of points k, we can determine from these values ​​when the number allowed to pass through the intermediate when k is less than or equal node, the shortest path length between them. Also, compared to the original situation, the new cases allowed intermediate node in the path of the new node number is k, the same way we determine the edge [i] [k] + edge [k] [j] value Edge value [i] [j], and if the former is smaller the value represents the length of the shortest path from the new case node i to node j; otherwise, in the case where the new path length remains unchanged. 

As noted earlier, in the adjacency matrix notation, Edge [i] [j] is represented by an intermediate node i to node j at the shortest distance without passing through any node, we were allowed to pass through the intermediate node Add 1 point node, node 2, node until ...... N , when these nodes have added from node i to node j allowed to pass through the shortest path length of all nodes can be determined, i.e., the length i is a node on the original path length to node j.

We set shortest path length ANS [k] [i] [j] is j permit from node i to node k or less through the node number . As described above, ans [0] [i] [j] is equal to the value graph adjacency matrix representation of the edge [i] [j] is. We adopt the following cycle, the completion of all k corresponding ans [k] [i] [ j] value solving:

for ( int K = 1 ; K <= n; K ++) // from 1 to n cycle K 
{
     for ( int I = 1 ; I <= n; I ++ ) 
    { 
        for ( int J = 1 ; J <= n; ++ J) // traverse all I, J 
        {
             iF (ANS [K - . 1 ] [I] [K] == ANx infinite || [K - . 1 ] [K] [J] == infinity) // when allowed passes before the k-1 nodes, i, j and k can not China Unicom, the date does not exist between the path through k ij of the 
            { 
                ANS [k] [I] [J] = ANS [k - . 1 ] [I ] [J]; //Is asserted, i.e., from i to j k points before and after allowing the same path length of time elapsed before the k-1 nodes 
                Continue ; 
            } 
            IF (ANS [k - . 1 ] [i] [j] == infinity | | ANx [K - . 1 ] [I] [K] + ANS [K - . 1 ] [K] [J] <ANS [K - . 1 ] [I] [J]) ANS [K] [I] [J] ANx = [k - . 1 ] [I] [k] + ANS [k - . 1 ] [k] [J]; // after the first k-1 nodes, i, j does not communicate or may be obtained through node k shorter path, the minimum value update 
            the else ANS [K] [I] [J] ANS = [K - . 1 ] [I] [J]; 
        } 
    } 
}

After n cycles this, we can obtain all the nodes allowed to pass between the path length under conditions of all the nodes, the path length is the shortest path length our requirements. That is, if required to obtain the shortest path length between ab, the answer is ans [n] [a] [b] value. 

We noticed that we through ans [k - 1] to a value obtained by recursive ans [k] [i] [j] of [i] [j] for each value, all ans [k] [i] [j] value by ans [k - 1] [i] [j] and the ans [k - 1] [i] [k] + ans [k - 1] [k] [j] of the size relationship is determined, but ans [k] [i] [k] and the ans [k] [k] [j] must be the ans [k - 1] [i] [k] and the ans [k - 1] [k] [j] value the same that these values ​​will not change because of this update occurs. The above code snippet we simplified into the following form: 

for ( int K = 1 ; K <= n; K ++) // from 1 to n cycle K 
{
     for ( int I = 1 ; I <= n; I ++ ) 
    { 
        for ( int J = 1 ; J <= n; ++ J) // traverse all I, J 
        {
             IF (ANS [I] [K] == infinite || anx [k] [j] == infinite) Continue ;
             IF (ANS [I] [J] == infinity ANx || [I] [K] + ANS [K] [J] <ANS [I] [J]) ANS [I] [J] = ANx [I] [K] + ANS [K] [J]; 
        } 
    } 
}

As shown in the code fragment, the original three-dimensional array will be reduced to a two-dimensional array, and each update updates directly on the two-dimensional array. This is the reason, when the outermost loop of k - 1 becomes k, each value ans [i] [k] and the ans [k] [j] will not be changed because this update (to current i k is the shortest path way through node k will not) , and this in turn update their respective values and the ans [i] [j] value comparison carried out. So we direct this update on a two-dimensional array, and will not affect the determination of this value is updated in each other . Saves a lot of memory space, while maintaining the original value of the operation is omitted.

Example 5.5 Shortest 

Problem-solving ideas

This example is the simplest of the shortest path problem. We first analyze the complexity, we have given as the code shown in the foregoing, Floyd algorithm including a triple loop, each loop iteration cycle times are N, Floyd such time complexity of the algorithm is O (N ^ 3) space complexity is O (N ^ 2), where N is the number of nodes in both FIG.

In the present embodiment the maximum value of N is 100, the N ^ 3 time complexity we still acceptable range. 

AC Code

#include <cstdio> int ANS [ 101 ] [ 101 ]; // two-dimensional array, which is the initial value of the graph adjacency matrix int main () 
{ int n-, m;
     the while (Scanf ( " % D% D " !, & n-, & m) = the EOF) 
    { IF (n-== 0 && m == 0 ) BREAK ;
         for ( int I = . 1 ; I <= n-; I ++ ) 
        { for ( int J = . 1 ; J <= n- ; J ++ ) 
            {




    
        
             
                ANS [I] [J] = - . 1 ; // initialize the adjacency matrix, with -1 for infinite 
            } 
            ANS [I] [I] = 0 ; // initializes to their own path length is 0 
        }
         the while (M- -) // read path 
        {
             int A, B, C; 
            Scanf ( " % D% D% D " , & A, & B, & C); 
            ANS [A] [B] = ANS [B] [A] = C; // undirected graphs, the two assignment 
        }
         for ( int K = . 1 ; K <= n-; K ++ ) 
        { 
            for ( inti = 1 ; i <= n; i ++ ) 
            { 
                for ( int j = 1 ; j <= n; j ++ ) 
                { 
                    if (years [i] [k] == - 1 || years [k] [j] == - 1 ) continues ;
                    if (years [i] [j] == - 1 || years [i] [k] + years [k] [j] <years [i] [j]) years [i] [j] = years [i ] [k] + years [k] [j]; 
                } 
            } 
        } 
        Printf ( " % d \ n " , years [ 1 ] [n]); 
    } 
    Return  0 ;
}
AC Code

Guess you like

Origin www.cnblogs.com/yun-an/p/11089120.html