From PM to PM, I have been doing this for a long time. I didn't use dij + heap to solve the problem, but all of them were SPFA, the one who maintains the graph with two arrays is really awesome. Although I have been reading it for a long time, I just want to use an example for comparison.
I was frustrated with the time-out of the previously written adjacent table TLE. Then I implemented the problem based on the problem solution. I used two arrays to maintain the image + SPFA, and I/O mounting,, 1000 ms (subject requirements: 8000 ms)
I tried it later. The vector was really slow. Expected
Then I looked back at my own neighbor list and suddenly found that push_back was a bit of a 2-way. I traversed the node from the first node to the tail, and then inserted the node into the tail, use a pointer to remember the position of the tail. After the end point is inserted, update the position of the tail and change the complexity from O (n) to O (1)
Okay. Let's just look at other questions. If you have time, see how to get dij + heap.
There are still a lot of comments this time.
/* Solve the AC code according to the question. The last two arrays of link used to save the graph do not need to be cleared. It is actually good */# include
# Include
# Include
# Include
# Include
Using namespace std; long N, E; const long MAXN = 1000001; const long INF = (1 <27)-1; bool visit [MAXN]; long dis [MAXN]; long que [MAXN]; struct eg {long to, v, pre;} link [2] [MAXN]; long last [2] [MAXN]; inline void SPFA (long kind) // 0 is positive, 1 is negative {// memset (dis, INF, sizeof (long) * (N + 1); memset (visit, 0, sizeof (bool) * (N + 1); // fill (dis + 1, dis + N + 1, INF); for (long I = 1; I <= N; I ++) {dis [I] = (1 <31) -1;} long start = 0; long end = 1; que [0] = 1; dis [1] = 0; long nowedge; while (start
Dis [nowvert] + link [kind] [nowedge]. v) {if (! Visit [to]) {que [end ++] = to; visit [to] = true ;} dis [to] = dis [nowvert] + link [kind] [nowedge]. v;} nowedge = link [kind] [nowedge]. pre; // remember to transfer nowedge by chain here} inline long Scan () // enter the plug-in {long res = 0, ch, flag = 0; if (ch = getchar () = '-') flag = 1; else if (ch> = '0' & ch <= '9 ') res = ch-'0'; while (ch = getchar ()> = '0' & ch <= '9 ') res = res * 10 + ch-'0'; return flag? -Res: res;} inline void Out (long a) // output plug-in {if (a> 9) Out (a/10 ); putchar (a % 10 + '0');} int main () {# ifndef ONLINE_JUDGEfreopen ("G:/1.txt"," r ", stdin); freopen (" G: /2.txt", "w", stdout); # endiflong long T; // scanf ("% lld", & T); T = Scan (); while (T --) {// scanf ("% lld", & N, & E); N = Scan (); E = Scan (); memset (last,-1, sizeof (last); for (long I = 1; I <= E; I ++) // graph creation part {long a, B, v; // scanf ("% lld", & a, & B, & v); a = Scan (); B = Scan (); v = Scan (); link [0] [I]. to = B; link [0] [I]. v = v; link [0] [I]. pre = last [0] [a]; // The last vertex records the number of the last edge from point a before the current edge is added, as the precursor of this edge, last [0] [a] = I; // corresponding, the current edge is the last edge that appears from point, record the serial number of this edge link [1] [I]. to = a; link [1] [I]. v = v; link [1] [I]. pre = last [1] [B]; last [1] [B] = I;} // calculate the shortest path of SPFA (0); long sum = 0; for (long I = 2; I <= N; I ++) sum + = dis [I]; SPFA (1); for (long I = 2; I <= N; I ++) sum + = dis [I]; // printf ("% lld \ n", sum); Out (sum ); putchar ('\ n') ;}}/* bug point: long longdis [1] = 0visit update */
/* When vector is used, it times out, mainly because there are still too many points and there are about 1 million. Although 8 seconds are given, although OI is used, local testing will also have 6 sides, it takes 0.8 seconds. Students say STL applies to around days... */# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; struct node {long to, v ;}; long N, E; const long MAXN = 1000001; const long INF = (1 <27) -1; bool visit [MAXN]; long dis [MAXN]; long que [MAXN]; vector
G [2] [MAXN]; inline void SPFA (long kind) // 0 is positive, 1 is negative {// memset (dis, INF, sizeof (long) * (N + 1); memset (visit, 0, sizeof (bool) * (N + 1); // fill (dis + 1, dis + N + 1, INF); for (long I = 1; I <= N; I ++) {dis [I] = (1 <31)-1 ;} long start = 0; long end = 1; que [0] = 1; dis [1] = 0; while (start
Dis [nowvert] + G [kind] [nowvert] [I]. v) {if (! Visit [to]) {que [end ++] = to; visit [to] = true ;} dis [to] = dis [nowvert] + G [kind] [nowvert] [I]. v ;}}} inline long Scan () // input ins {long res = 0, ch, flag = 0; if (ch = getchar ()) = '-') flag = 1; else if (ch> = '0' & ch <= '9') res = ch-'0 '; while (ch = getchar ()> = '0' & ch <= '9') res = res * 10 + ch-'0'; return flag? -Res: res;} inline void Out (long a) // output plug-in {if (a> 9) Out (a/10 ); putchar (a % 10 + '0');} int main () {# ifndef ONLINE_JUDGEfreopen ("G:/1.txt"," r ", stdin); freopen (" G: /2.txt", "w", stdout); # endiflong long T; // scanf ("% lld", & T); T = Scan (); while (T --) {// scanf ("% lld", & N, & E); N = Scan (); E = Scan (); struct node z, f; for (long I = 1; I <= E; I ++) // graph creation part {long a, B, v; // scanf ("% lld", & a, & B, & v); a = Scan (); B = Scan (); v = Scan (); z. to = B; z. v = v; f. to = a; f. v = v; G [0] [a]. push_back (z); G [1] [B]. push_back (f) ;}// obtain the SPFA (0) for the shortest short-circuit part; long sum = 0; for (long I = 2; I <= N; I ++) sum + = dis [I]; SPFA (1); for (long I = 2; I <= N; I ++) sum + = dis [I]; // printf ("% lld \ n", sum); Out (sum); putchar ('\ n'); for (int I = 0; I <2; I ++) {for (int j = 1; j <= N; j ++) {G [I] [j]. clear ();}}}}
/* This is my own list of adjacent tables, and it's also TLE. I'm angry and want to know why this is so slow */# include
# Include
# Include
# Include
# Include
# Include
Using namespace std; struct edge {long to, cost ;}; const long MAXN = 1000001; const long INF = (1 <30)-1; struct GRAPH // struct {struct edge e; GRAPH * next; void push_back (edge add) // simulate vector {GRAPH * poin = this; while (poin-> next) {poin = poin-> next;} GRAPH addme; addme. e = add; poin-> next = new GRAPH; * (poin-> next) = addme;} GRAPH () // The next pointer must be 0 at the beginning, G [v] is the header node. G [v]-> next and later Save the edge {next = 0;} G [2] [MAXN]; long N, e; bool visit [MAXN]; long dis [MAXN]; long que [MAXN]; inline void SPFA (long kind) // 0 is positive, 1 is negative {// memset (dis, INF, sizeof (long) * (N + 1); memset (visit, 0, sizeof (bool) * (N + 1); fill (dis + 1, dis + N + 1, INF); // for (long I = 1; I <= N; I ++) // {// dis [I] = (1 <30)-1; //} long start = 0; long end = 1; que [0] = 1; dis [1] = 0; while (start
Dis [nowvert] + G [kind] [nowvert] [I]. v) // {// if (! Visit [to]) // {// que [end ++] = to; // visit [to] = true; /// dis [to] = dis [nowvert] + G [kind] [nowvert] [I]. v; //} GRAPH * poin = & G [kind] [nowvert]; poin = poin-> next; while (poin) {edge e = poin-> e; if (dis [e. to]> dis [nowvert] + e. cost) {if (! Visit [e. to]) {que [end ++] = e. to; visit [e. to] = true;} dis [e. to] = dis [nowvert] + e. cost;} poin = poin-> next ;}} inline long Scan () // input plug-in {long res = 0, ch, flag = 0; if (ch = getchar () = '-') flag = 1; else if (ch> = '0' & ch <= '9 ') res = ch-'0'; while (ch = getchar ()> = '0' & ch <= '9 ') res = res * 10 + ch-'0'; return flag? -Res: res;} inline void Out (long a) // output plug-in {if (a> 9) Out (a/10 ); putchar (a % 10 + '0');} int main () {# ifndef ONLINE_JUDGEfreopen ("G:/1.txt"," r ", stdin); freopen (" G: /2.txt", "w", stdout); # endiflong long T; // scanf ("% lld", & T); T = Scan (); while (T --) {// scanf ("% lld", & N, & E); N = Scan (); E = Scan (); struct edge z, f; for (long I = 1; I <= E; I ++) // graph creation part {long a, B, v; // scanf ("% lld", & a, & B, & v); a = Scan (); B = Scan (); v = Scan (); z. to = B; z. cost = v; f. to = a; f. cost = v; G [0] [a]. push_back (z); G [1] [B]. push_back (f) ;}// obtain the SPFA (0) for the shortest short-circuit part; long sum = 0; for (long I = 2; I <= N; I ++) sum + = dis [I]; SPFA (1); for (long I = 2; I <= N; I ++) sum + = dis [I]; // printf ("% lld \ n", sum); Out (sum); putchar ('\ n'); memset (G, 0, sizeof (G ));}}
/* It's so cool to get it out. After optimizing push_back, the original adding node is scanned from the beginning to the tail, and now a pointer is added to remember the tail */# include
# Include
# Include
# Include
# Include
# Include
Using namespace std; struct edge {long to, cost ;}; const long MAXN = 1000001; const long INF = (1 <30)-1; struct GRAPH // struct {struct edge e; GRAPH * next; GRAPH * pLast; int thefirst; void push_back (edge & add) // imitation vector {if (thefirst) {pLast = this; thefirst = 0;} pLast-> next = new GRAPH; pLast = pLast-> next; GRAPH addme; addme. e = add; * (pLast) = addme;} void clear () {next = 0; pLast = this;} GRAPH () // The next pointer must be 0 at the beginning, G [v] is the header node. G [v]-> next and later Save the edge {next = 0; thefirst = 1; // pLast = this; // This GRAPH object has not yet been generated, so it is incorrect to use it;} G [2] [MAXN]; long N, E; bool visit [MAXN]; long dis [MAXN]; long que [MAXN]; inline void SPFA (long kind) // 0 is positive, 1 is negative {// memset (dis, INF, sizeof (long) * (N + 1); memset (visit, 0, sizeof (bool) * (N + 1); fill (dis + 1, dis + N + 1, INF); // for (long I = 1; I <= N; I ++) // {// dis [I] = (1 <30)-1; //} long start = 0; long end = 1; que [0] = 1; dis [1] = 0; while (start
Dis [nowvert] + G [kind] [nowvert] [I]. v) // {// if (! Visit [to]) // {// que [end ++] = to; // visit [to] = true; /// dis [to] = dis [nowvert] + G [kind] [nowvert] [I]. v; //} GRAPH * poin = & G [kind] [nowvert]; poin = poin-> next; while (poin) {edge e = poin-> e; if (dis [e. to]> dis [nowvert] + e. cost) {if (! Visit [e. to]) {que [end ++] = e. to; visit [e. to] = true;} dis [e. to] = dis [nowvert] + e. cost;} poin = poin-> next ;}} inline long Scan () // input plug-in {long res = 0, ch, flag = 0; if (ch = getchar () = '-') flag = 1; else if (ch> = '0' & ch <= '9 ') res = ch-'0'; while (ch = getchar ()> = '0' & ch <= '9 ') res = res * 10 + ch-'0'; return flag? -Res: res;} inline void Out (long a) // output plug-in {if (a> 9) Out (a/10 ); putchar (a % 10 + '0');} int main () {# ifndef ONLINE_JUDGEfreopen ("G:/1.txt"," r ", stdin); freopen (" G: /2.txt", "w", stdout); # endiflong long T; // scanf ("% lld", & T); T = Scan (); while (T --) {// scanf ("% lld", & N, & E); N = Scan (); E = Scan (); struct edge z, f; for (long I = 1; I <= E; I ++) // graph creation part {long a, B, v; // scanf ("% lld", & a, & B, & v); a = Scan (); B = Scan (); v = Scan (); z. to = B; z. cost = v; f. to = a; f. cost = v; G [0] [a]. push_back (z); G [1] [B]. push_back (f) ;}// obtain the SPFA (0) for the shortest short-circuit part; long sum = 0; for (long I = 2; I <= N; I ++) sum + = dis [I]; SPFA (1); for (long I = 2; I <= N; I ++) sum + = dis [I]; // printf ("% lld \ n", sum); Out (sum); putchar ('\ n'); // memset (G, 0, sizeof (G); for (int I = 0; I <2; I ++) {for (int j = 1; j <= N; j ++) {G [I] [j]. clear ();}}}}