This topic deepens my understanding of the source of the difference constraint.
This is to determine whether the graph has a ring (using the shortest or shortest path), and start to use spfa, crazy wa. I can't figure it out. After reading the discussion, I said I would like to add a supersource point, once added, the AC is ready.
Conclusion: Using spfaAlgorithmTo determine whether a ring exists in the graph, we must ensure that each vertex can be reached from the source point, so as to ensure that the inequality in the difference constraint is true. If the Source Vertex cannot reach a vertex (that is, the graph is not connected), then the vertex cannot be joined. As a result, all the inequalities starting from the vertex are not checked.
Instead, we use the bellman_ford algorithm, so we do not need to add a supersource point. Because it performs n-1 relaxation on each edge in the graph, every vertex is updated.
# Include <iostream> # include <queue> using namespace STD; const int max = 500000; const int INF = 1000000000; const int n = 2000; struct node {int V; int cost; int next;}; node [Max]; int CNT [N]; int adj [N]; bool in_q [N]; int d [N]; int size; int n, m; void add_edge (int u, int V, int cost) {node [size]. V = V; node [size]. cost = cost; node [size]. next = adj [u]; adj [u] = size ++;} bool spfa () {queue <int> q; memset (CNT, 0, Si Zeof (CNT); memset (in_q, false, sizeof (in_q); For (INT I = 0; I <= N; I ++) d [I] =-INF; int U, V, W; // search for d [0] = 0 from a supersource vertex; in_q [0] = true; q. push (0); While (! Q. Empty () {u = Q. Front (); q. Pop (); in_q [u] = false; For (INT I = adj [u]; I! =-1; I = node [I]. next) {v = node [I]. v; W = node [I]. cost; If (d [v] <D [u] + W) {d [v] = d [u] + W; If (! In_q [v]) {in_q [v] = true; q. push (V); If (++ CNT [v]> = N) return false ;}}}return true;} bool bellman_ford () {for (INT I = 0; I <= N; I ++) d [I] =-INF; bool isfinish; For (INT I = 1; I <= N; I ++) {isfinish = true; For (INT u = 0; U <= N; U ++) for (int K = adj [u]; k! =-1; k = node [K]. next) if (d [node [K]. v] <D [u] + node [K]. cost) {d [node [K]. v] = d [u] + node [K]. cost; isfinish = false;} If (isfinish) break;} For (INT u = 0; U <= N; U ++) for (int K = adj [u]; k! =-1; k = node [K]. next) if (d [node [K]. v] <D [u] + node [K]. cost) return false; return true;} int main () {char C; int A, B, W; while (scanf ("% d", & N, & M )! = EOF) {size = 0; For (INT I = 0; I <= N; I ++) adj [I] =-1; for (INT I = 0; I <m; I ++) {getchar (); scanf ("% C", & C); If (C = 'P ') {scanf ("% d", & A, & B, & W); add_edge (B, A, W); add_edge (A, B, -W);} else if (C = 'V') {scanf ("% d", & A, & B); add_edge (B,, 1);} // you do not need to add a supersource vertex when using bellman. // Add the edge of the supersource vertex to all vertices. // For (INT I = 1; I <= N; I ++) // add_edge (0, I, 0); If (bellman_ford () printf ("reliable \ n"); elseprintf ("unreliable \ n ");} return 0 ;}