The article is not original, reproduced ~ ~
summer vacation, Xiao Hum is going to travel to some cities. Some cities have highways, and some cities do not, such as. To save money and make it easier to plan your trip, Xiao Hum hopes to know the shortest distance before departing any two cities before departure. There are 8 highways in 4 cities, and the numbers on the highways indicate the length of the road. Please note that these highways are one-way. We now need to find the shortest distance between any two cities, that is, the shortest path between any two points. This problem is also known as the "multi-source Shortest path" problem. now requires a data structure to store the information of the graph, we can still use a 4*4 matrix (two-dimensional array e) to store. For example, City 1th to City 2nd is 2, then set e[1][2] to a value of 2. City No. 2nd cannot reach City 4th, the value of setting e[2][4] is ∞. In addition here the Convention a city itself is to own also 0, for example E[1][1] for 0, specifically as follows. Now back to the question: how to find the shortest path between any two points? Through previous studies we know that the shortest path between two points can be found through depth or breadth-first search. So n2 the depth or breadth of the first search, that is, every two points of a depth or breadth first search, you can find any two points between the shortest path. But is there any other way? Let's think, according to our previous experience, if you want to shorten the distance between any two points (for example, from vertex A to vertex B), you can only introduce a third point (vertex K) and pass through this vertex k to relay that a->k- >b, it is possible to shorten the distance from vertex a point to vertex b. So what is the point in the 1~n that this relay vertex k is? Sometimes it is even shorter to pass through two or more points, not just through a point, a->k1->k2b-> or a->k1->k2...->k->i...->b. For example, the distance from city 4th to City 3rd (4->3) e[4][3] was originally 12. If you only pass through City 1th (4->1->3), the journey will be shortened to one (e[4][1]+e[1][3]=5+6=11). In fact, City 1th to 3rd City can also transit through the city of 2nd, making the 1th to 3rd city journey shortened to 5 (e[1][2]+e[2][3]=2+3=5). So if you go through two cities at 1th and 2nd, the road from City 4th to city 3rdFurther shorten the process to 10. With this example, we find that each vertex has the potential to shorten the distance between the other two vertices. OK, let's generalize this question. When a third point is not allowed between any two points, the shortest distance between these cities is the initial distance, as follows.
What if the shortest distance between any two points is allowed to go through only 1th vertices now? Just determine if E[I][1]+E[1][J] is smaller than e[i][j]. E[I][J] represents the distance from the I vertex to the J number vertex. E[I][1]+E[1][J] Represents the sum of the distances from vertex i to number 1th, and from vertex number 1th to vertex J. Where I is the 1~n loop, and J is also the 1~n loop, the code is implemented as follows.
for (i=1; i<=n;i++) for (j=1; j<=n;j++) if (e[i][j]>e[i][1]+e[1][j]) e[i][j]=e[i][1]+e[1
In cases where only 1th vertices are allowed, the shortest distance between any two points is updated to:
We found that the distances from vertex 3rd to vertex 2nd (e[3][2]), vertex 4th to Vertex 2nd (e[4][2]), and 4th vertices to 3rd vertices (e[4][3]) were shortened when only the 1th vertices were brokered. Next, continue to ask for the shortest distance between any two points that only allow two vertices of 1 and 2nd. How to do it? We need to be able to take the shortest distance of any two points when only the 1th vertex is allowed, and then determine if passing the vertex number 2nd will make the distance between the I vertex and the J vertex shorter. That is to judge E[i][2]+e[2][j] is smaller than e[i][j], the code is implemented as follows:
// after vertex number 1th for (i=1; i<=n;i++) for (j=1; j<=n;j++) if (e[i][j]>e[i][1]+e[1][j]) e[i][j]=e[i][1]+e[1 ][j];
// after vertex number 2nd for (i=1; i<=n;i++) for (j=1; j<=n;j++) if (e[i][j]>e[i][2]+e[2][j]) e[i][j]=e[i][2]+e[2[ J];
In cases where only 1 and 2nd vertices are allowed, the shortest distance between any two points is updated to:
By knowing that, when compared to only allowing transit through the number 1th vertices, this allows the transfer through vertices 1 and 2nd, making e[1][3] and e[4][3] shorter distances. In the same vein, the shortest distance between any two points is continued in cases where only 1, 2, and 3rd vertices are allowed to be brokered. The shortest distance between any two points is updated to: finally allow all vertices as a transit, the final shortest distance between any two points is: the entire algorithm process, although it is very cumbersome, but the code implementation is very simple, the core code only five elements:
for (k=1; k<=n;k++) for (i=1; i<=n;i++) for (j=1; j<=n;j++) if (e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j];
The basic idea of this code is that it is only allowed to go through the number 1th vertices at first, and then only the 1 and 2nd vertices are allowed to relay ... The shortest distance between any two points is allowed through all vertices of the 1~n number. In a nutshell: From the I vertex to the J vertex only passes the shortest distance from the front K points.
#include <stdio.h>intMain () {inte[Ten][Ten],k,i,j,n,m,u,v,w; intinf=99999999;//use INF (infinity abbreviation) to store a positive infinity value we think//reads N and m,n to indicate the number of vertices, m represents the number of edgesscanf"%d%d",&n,&m); //Initialize for(i=1; i<=n;i++) for(j=1; j<=n;j++) if(I==J) e[i][j]=0; Elsee[i][j]=inf; //Read in Edge for(i=1; i<=m;i++) {scanf (" %d%d%d",&u,&v,&W); E[U][V]=W; } //Floyd-warshall algorithm Core statement for(k=1; k<=n;k++) for(i=1; i<=n;i++) for(j=1; j<=n;j++) if(e[i][j]>e[i][k]+E[k][j]) e[i][j]=e[i][k]+E[k][j]; //output The final result for(i=1; i<=n;i++) { for(j=1; j<=n;j++) {printf ("%10d", E[i][j]); } printf ("\ n"); } return 0; }
It is also important to note that the Floyd-warshall algorithm cannot solve a graph with a "negative weight loop" (or "negative weight loop") because there is no shortest path with a "negative weight loop" diagram. For example, the following figure does not have the shortest path from vertex number 1th to vertex 3rd. Because 1->2->3->1->2->3->...->1->2->3 such a path, each time around a 1->-2>3 such a ring, the shortest path will be reduced by 1, never find the shortest way. In fact, if a figure with a "negative weight loop" then this diagram is not the shortest way.
Freud algorithm (Floyd-warshall)