The previous spfa or Floyd was only used to find the shortest path, and there was no concept about how to print the path.
Maybe it's because I don't quite understand the principle?
In short, I took a quick look, and now I finally understand my understanding... Mark
In the morning, I encountered a bare short-circuit problem: vijos1635.
1. First, let's talk about the spfa method:
In fact, the most recently used spfa is on the grid, that is, two-dimensional
One-dimensional adjacent table + queue
As well as queue operations, they are also drunk
Paste a template (excluding the print path) here ):
# Include <cstdio> # include <cstring> # include <queue> # include <iostream> using namespace STD; const int maxn = 10100; int n, m, K, T, x, Y, S, ANS = 0; long tot = 0; struct edge {int from, to, W, next;} e [10100000]; int head [maxn], dist [maxn]; bool vis [maxn]; void add (int x, int y, int Z) {// adjacent Table E [tot]. from = x; E [tot]. to = y; E [tot]. W = z; E [tot]. next = head [X]; head [x] = tot ++;} void spfa (INT s) {queue <int> q; memset (Dist, 63, sizeof (DIST); memset (VIS, false, sizeof (VIS); // I think the value assignment here is slightly different from the two-dimensional one. Here it is the initial value falseq. push (s); Dist [s] = 0; while (! Q. empty () {int u = Q. front (); q. pop (); vis [u] = false; ② For (INT I = head [u]; I! =-1; I = E [I]. next) {int v = E [I]. to; If (Dist [v]> Dist [u] + E [I]. w) {Dist [v] = DIST [u] + E [I]. w; If (! Vis [v]) {// if you have already joined the queue, or the initial value is ① vis [v] = true; q. push (v) ;}}}} int main () {scanf ("% d", & N); memset (Head,-1, sizeof (head )); // remember that the head value is-1for (INT I = 1; I <= N; I ++) for (Int J = 1; j <= N; j ++) {scanf ("% d", & S); If (s! = 0) {Add (I, j, S) ;}} spfa (1); printf ("% d", DIST [N]); Return 0 ;}
Have a good feeling ① and ②
Spfa print path problems:
Here we need to use the pointer idea to find the precursor of N.
So if the DIST has an update value, record it, but here we need to understand,
What you recorded is not recorded based on the path sequence.
To put it bluntly, F [1] is not the first path.
Instead, let v-> U. This is what F should do.
If (Dist [v]> Dist [u] + E [I]. W) {Dist [v] = DIST [u] + E [I]. W;
F [v] = u; // Add this value after the updated value
If (! Vis [v]) {vis [v] = true; q. Push (V );}
}
And call a recursive function to find the precursor:
void printpath(int k){ if(k!=0){ printpath(f[k]); printf("%d ",k); }}
2. Floyd algorithm:
Add a statement after the update value:
K = 1-N
I = 1-N
J = 1-N
If (...> ..)
Dist [I] [J] = DIST [I] [k] + dist [k] [J];
F [I] [J] = f [I] [k];
For (V = 0; v <n; ++ v) {for (W = V + 1; W <n; W ++) {printf ("% d-> % d: % d", V, W, d [v] [W]); k = P [v] [W]; /* obtain the first path vertex subscript */printf ("Path: % d", V);/* print the Source Vertex */while (K! = W)/* If the path vertex subscript is not the end */{printf ("-> % d", k ); /* print the path vertex */k = P [k] [W];/* obtain the subscript of the next path vertex */} printf ("-> % d \ n ", w);/* print the end */} printf ("\ n ");}