Floyd Discrete, Minimum ring

Source: Internet
Author: User

Description

Hangzhou has n scenic spots, there are some two-way connection between scenic spots, now 8600 want to find a tourist route, this route from a point and finally back to a point, assuming the route is V1,v2,.... VK,V1, then must meet the k>2, that is, apart from the starting point to go through at least 2 other different scenic spots, and can not be repeated through the same scenic area. Now 8600 needs you to help him find a route like this, and the less it costs the better.

Input

The first line is 2 integers n and m (n <=, M <= 1000), representing the number of scenic areas and the number of roads.
In the next M-line, each row consists of 3 integers a,b,c. Represents a path between A and B and costs C (c <= 100).

Output

For each test instance, the minimum value of the output is spent if such a route can be found. If it is not found, output "It's impossible."

Sample Input

3 31 2 12 3 11 3 13 31 2 11 2 32 3 1

Sample Output

3It ' s impossible.
for finding the smallest ring, and going through at least two nodes, weights and minimums, the algorithm is Floyd, but the place of attention and understanding is a lot1. Definition and understanding: Transfer from http://leon.cc.blogbus.com/logs/3629782.htmlThis problem is often encountered in graph theory, where the shortest distance between any two nodes is calculated in a graph. We have encountered this problem in the discrete mathematics, the data structure class, in the computer network Introduction network layer of time seems to have encountered this problem, remember not to please ... But all the books are taken is the Dijkstra algorithm, through the Dijkstra algorithm can find the shortest path single source, and then use the Dijkstra algorithm on a per node basis can be. But for a change of tastes here, take the algorithm Robert Floyd proposed to solve this problem. Let's start by formalizing the question a little bit: if there is a matrix D=[d (IJ)], where D (IJ) >0 represents the distance of I city to J City. If there is no way between I and J, then D (IJ) is infinity. and d (ii) =0.     Write a program that uses this distance matrix D to find the shortest path between any two cities and their behavior. We can decompose the problem, find the shortest distance, and then consider how to find the corresponding road path. How to find the shortest path, here is still using the knowledge of dynamic planning, for any city, I to J shortest distance is the existence of the k between I and J and not through K two possible, so can make K=1,2,3,..., N (n is the number of cities), check the value of D (IJ) and D (IK) +d (kj), where D (IK) and D (KJ) are the shortest distances known to I to K and K to J, respectively, so D (IK) +d (kj) is the shortest distance from I to J through K. So, if there is D (IJ) >d (ik) +d (kj), it means that the distance from I to go through K to J is shorter than the original I-J distance, naturally I to J D (IJ) is rewritten as D (IK) +d (KJ), whenever a k is checked, D (IJ) is the shortest distance from the current I to J. Repeat this process, and finally, when all k is checked, the shortest distance between I and J is stored in D (IJ).                     So we can use three for loops to fix the problem, but there is one problem to be aware of, which is the nesting order of the FOR loop: we may be able to write such a program at hand, but if we think about it, we will find it problematic.  for(intI=0; i<n; i++)                            for(intj=0; j<n; J + +)                                 for(intk=0; k<n; k++The problem is that we are too early to put I-k-j's distance was determined, assuming that once the i-p-was found,J The shortest distance, I to J is quite finished, and will not change in the future, once I to J of the shorter distance can not be updated, so the result must be wrong. So you should write the program as follows: for(intk=0; k<n; k++)                          for(intI=0; i<n; i++)                               for(intj=0; j<n; J + +The significance of this is to fix K, all I to J and the distance through K to find out, and then as mentioned in the beginning to compare and rewrite, because K is in the outermost, so will all the I to J are processed, will move to the next K, so there is no problem, it seems that the multi-layer cycle,     We must be careful, otherwise it is easy to make a mistake. The next step is to look at how to find the shortest path of the city, and here to use another matrix p, which is defined as: P (IJ) if the value of p, it means I to J shortest passes for I->...->p->j, that is, p is the last city before J in the shortest act of I to J. The initial value of the P-matrix is P (IJ) =i. With this matrix, it is easy to find the shortest path. For I to J to find P (IJ), so that p, I know the path i->...->p->j; again to find P (IP), if the value of Q,i to p the shortest path for i->...->q->p; to find P (IQ), if the value is R, I to q the shortest path is i->...->r->q; so repeatedly, to a certain p (it) value is I, the shortest path I to T is i->t, will be to the answer, I to J of the shortest act of i->t->...-> Q->p->J.     Because the above algorithm is from the end point to the beginning of the order to find out, so the output of the time to turn it upside down. However, how to dynamically backfill the values of P-matrices? Recall that when D (IJ)>d (IK) +d (kj), it is necessary to change the shortest path of I to J to go i->...->k->...->j this way, but the value of D (KJ) is known, in other words, k->...->j This road is known, So k->...->j the last city of J on this road (ie, p (KJ)) is also known, of course, because to change the path of I->...->k->...->j, J's previous city is just P (KJ). So once found D (IJ) >d (IK) +d (KJ), p (KJ) is deposited in P (IJ). 2understanding of the code: [CPP] View Plaincopyprint?#include<iostream>#include<cstdio>#include<cstring>using namespacestd; #defineData 100000000#defineN 110#defineMin (x, y) ((×) > (y)? ( Y):(x))intMap[n][n],dis[n][n]; intn,m; voidFloyd () {intI,j,k,mina=data;  for(k=1; k<=n;k++)      {      //because the path I to J is only through K and not through K, and requires at least two nodes from a point to return to the origin, K each update will make DIS[I][J] updated, and only after the update of a k before you can find Min,min is in Dis[i][i] The shortest case is at least two points back to the minimum distance, so the values of I and J should be less than K,i value from 1 to k-1, while the value of J is related to the value of I, that is i!=j, because when I=j, Dis[i][j] is not infinity, but from the value of I->j->i, This will appear self-ring, where I define the self-loop to go through a node to return to the original node node, such as 1->2->1 such as the value of min will not be accurate, this is not through two nodes, so the following first two-layer loop can have three kinds of writing, the specific look at the code//when you want to expand the K-node, the first k-1 node has been used, and is used to update the shortest path Dis[i][j] This is the second two-tier for loop, so there is a shortest path from I to J before updating K, and then looking for another path from I to J, Map[j][k ]+map[k][i], if any, must have formed a ring from I back to I, such as the 1->2 value of 1,2->3 value of 2,3->4 value for the 3,4->1 value of 4, then the first existence from 1 to 3 of the shortest, and then find the path of 1 to 4, 4 to 3, The ring is formed, and is the smallest, note that the value added in the first loop is map[j][k] and map[k][i], and that the value of the map is the initial value, does not change, and dis is constantly updated         for(i=1; i<k;i++)          {               for(j=i+1; j<k;j++) {Mina=min (dis[i][j]+map[j][k]+Map[k][i],mina); }          }           for(i=1; i<=n;i++)          {               for(j=1; j<=n;j++)              {                 if(Dis[i][j]> (dis[i][k]+Dis[k][j])) DIS[I][J]=dis[i][k]+Dis[k][j]; }          }      }      if(mina<data) printf ("%d\n", Mina); Elseprintf ("It ' s impossible.\n"); }  intMain () {inta,b,c,i,j;  while(SCANF ("%d%d", &n,&m)! =EOF) {           for(i=0; i<=n;i++)            for(j=0; j<=n;j++) {Map[i][j]=data; DIS[I][J]=data; }           for(i=0; i<m;i++) {scanf ("%d%d%d",&a,&b,&B); if(map[a][b]>c) {Map[a][b]=map[b][a]=C; DIS[A][B]=dis[b][a]=C;      }} Floyd (); }      return 0; This is the second type: [CPP] View Plaincopyprint?#include<iostream>#include<cstdio>#include<cstring>using namespacestd; #defineData 100000000#defineN 110#defineMin (x, y) ((×) > (y)? ( Y):(x))intMap[n][n],dis[n][n]; intn,m; voidFloyd () {intI,j,k,mina=data;  for(k=1; k<=n;k++)      {           for(i=1; i<k;i++)          {               for(j=1; j<i;j++) {Mina=min (dis[i][j]+map[j][k]+Map[k][i],mina); }          }           for(i=1; i<=n;i++)          {               for(j=1; j<=n;j++)              {                 if(Dis[i][j]> (dis[i][k]+Dis[k][j])) DIS[I][J]=dis[i][k]+Dis[k][j]; }          }      }      if(mina<data) printf ("%d\n", Mina); Elseprintf ("It ' s impossible.\n"); }  intMain () {inta,b,c,i,j;  while(SCANF ("%d%d", &n,&m)! =EOF) {           for(i=0; i<=n;i++)            for(j=0; j<=n;j++) {Map[i][j]=data; DIS[I][J]=data; }           for(i=0; i<m;i++) {scanf ("%d%d%d",&a,&b,&B); if(map[a][b]>c) {Map[a][b]=map[b][a]=C; DIS[A][B]=dis[b][a]=C;      }} Floyd (); }      return 0; This is the third type: [CPP] View Plaincopyprint?#include<iostream>#include<cstdio>#include<cstring>using namespacestd; #defineData 100000000#defineN 110#defineMin (x, y) ((×) > (y)? ( Y):(x))intMap[n][n],dis[n][n]; intn,m; voidFloyd () {intI,j,k,mina=data;  for(k=1; k<=n;k++)      {           for(i=1; i<k;i++)          {               for(j=1; j<k;j++) {Mina=min (dis[i][j]+map[j][k]+Map[k][i],mina); }          }           for(i=1; i<=n;i++)          {               for(j=1; j<=n;j++)              {               //Watch this i!=j .               if(I!=j&&dis[i][j]> (dis[i][k]+Dis[k][j])) DIS[I][J]=dis[i][k]+Dis[k][j]; }          }      }      if(mina<data) printf ("%d\n", Mina); Elseprintf ("It ' s impossible.\n"); }  intMain () {inta,b,c,i,j;  while(SCANF ("%d%d", &n,&m)! =EOF) {           for(i=0; i<=n;i++)            for(j=0; j<=n;j++) {Map[i][j]=data; DIS[I][J]=data; }             for(i=0; i<m;i++) {scanf ("%d%d%d",&a,&b,&c); if(map[a][b]>c) {Map[a][b]=map[b][a]=C; DIS[A][B]=dis[b][a]=C;      }} Floyd (); }      return 0; }  

Floyd Discrete, Minimum ring

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.