Question link: http://poj.org/problem? Id = 2485
A: There is no highways in a local area, and there is no high ways. There is no high ways of transportation. A high way connects two towns. All the high ways are straight lines.
Sample input meaning:
T case count
N towns
N rows and n columns below, in the form of a matrix
V1 V2 v3
V1 0 990 692
V2 990 0 179
V3 692 179 0
Sample output meaning:
The obvious path is the v1-v3-v2, the maximum number in the path is 692, and the output is it
Ideas:
Minimum Spanning Tree problem. Prim and kuskal algorithms are generally used. The prim algorithm is extended by vertices. Add each vertex to the vertex set U, and then find the smallest vertex adjacent to the U, add the U, and then obtain the minimum spanning tree.
Reference: http://en.wikipedia.org/wiki/prim's_algorithm
# Include <stdio. h> # include <string. h> # define M 502 # define INF 99999int prim [m] [m]; int visit [m]; int Len [m]; // Len [I] records the shortest distance from vertex set u to I. Note the difference between DIS [I] int N; int ans; int prim_solve (INT XX) {int Minx; int I, j, k; memset (visit, 0, sizeof (visit); // ans =-1; for (I = 1; I <= N; I ++) {Len [I] = prim [XX] [I];} Len [XX] = 0; visit [XX] = 1; // at this time, only the starting point XX for (I = 1; I <n; I ++) in U // Note: it cannot be =, because the starting point XX has been accessed, you only need Access n-1 {Minx = inf; For (j = 1; j <= N; j ++) // similar to Dijkstra, but note: the LEN [I] Here is quite different from the DIS [I] In Dijkstra {// here we are looking for the minimum value of the distance adjacent to the vertex set u if (! Visit [J] & Len [J] <Minx) {Minx = Len [J]; k = J ;}} visit [k] = 1; // locate, add u if (ANS <Minx) // Save the largest edge in the shortest path. For example, when 692 {ans = Minx;} // I = 1, in U, only the starting point XX and the newly added K are available. Len [J] is compared with prim [J: after comparing the distance from xx to J and the distance from the new K vertex to J, Len [J] is the shortest distance from u to J, in this way, all vertices in u are regarded as one, Len [J] is the shortest distance from u to J (any one in the V-U) // and so on, when I> 1, each time we compare the distance from the original vertex set u to J with the distance from the newly added K to J, so as to obtain the shortest distance from the new u to J, the distance from the new u to any vertex in the V-U is obtained and saved in Len for (j = 1; j <= N; j ++) {If (! Visit [J] & Len [J]> prim [k] [J]) {Len [J] = prim [k] [J] ;}} return ans ;} int main () {int t; int I, j; scanf ("% d", & T); While (t --) {memset (Prim, 0, sizeof (prim); scanf ("% d", & N); for (I = 1; I <= N; I ++) for (j = 1; j <= N; j ++) {scanf ("% d", & prim [I] [J]);} printf ("% d \ n ", prim_solve (1); // It can start with the first vertex, or it can be other. It doesn't matter, change it to 2 .... Same} return 0 ;}
You will think prim code implementation is coming like Dijkstra, refer to http://blog.csdn.net/bill_ming/article/details/7578037
Prim is the algorithm used to calculate the Minimum Spanning Tree, while Dijkstra is the algorithm used to calculate the shortest path.
They all choose from the geometric V-U to add the vertex with the smallest weight to the U, can they use each other?
No!
Their differences are:
Prim is to look at the point in the U into a whole, every time you look for the V-U and the smallest distance between the U vertex to join the U. Dijkstra is relative to the source point v0, each time looking for is the closest vertex of V0 in the V-U.
Therefore:
In Dijkstra, DIS [I] records the shortest distance from V0 to I.
This for loop is used to update dis. The result of DIS [J] is the result of comparing the shortest distance from the Source Vertex V0 to the Source Vertex V0 through K to J.
For (j = 1; j <= N; j ++)
{
If (! Visit [J] & dis [J]> dis [k] + map [k] [J])
{
Dis [J] = dis [k] + map [k] [J];
}
}
In Prim, Len [I] records the shortest distance from vertex set U (as a whole) to I.
This for loop is used to update the distance from vertex set u to any vertex in the V-U, comparing the distance from vertex set to J before K and the distance from K to J.
The obtained result is the shortest distance from the new vertex set u that contains K to J. (Thanks to Luo kangqi !!!)
// When I = 1, u only has the starting point XX and the newly added K. Len [J] and prim [J] are compared: is to compare the distance from xx to J and the distance from the K vertex with the new u to J.
// After that, Len [J] is the shortest distance from u to J, so that all vertices in u are regarded as one, Len [J] is u to J (any one in the V-U) the shortest distance
// Similarly, when I> 1, the distance from the original vertex set u to J is compared with the distance from the newly added K to J, the shortest distance from new u to J is obtained.
// Thus, the distance from the new u to any vertex in the V-U is obtained and saved in Len
For (j = 1; j <= N; j ++)
{
If (! Visit [J] & Len [J]> prim [k] [J])
{
Len [J] = prim [k] [J];
}
}
The difference is known. So we can't use each other. Prim should be the smallest spanning tree. Dijkstra should continue to manage the shortest path.
For example, we can see that they cannot be confused:
There are four vertices (v0,
V1, V2, V3) and four edges, and the edge value is defined as (v0,
V1) = 20, (v0, V2) = 10, (V1, V3) = 2, (V3, V2) = 15, v0 and V1 in the Minimum Spanning Tree obtained using the prim algorithm are not directly connected, that is, in the Minimum Spanning Tree, the distance between v0v1 is V0-> v2-> V3-> V1 is 27, and the distance between v0v1 is 20 using Dijkstra algorithm, that is, the length of the two direct connections.
So ....