Title: There are n delivery points, x bidirectional edges, y unidirectional edges, the starting point is s, the weights of bidirectional edges are all positive, the weights of unidirectional edges can be negative, and one is given for unidirectional edges Restriction: If u-> v holds, then v-> u must not hold. Ask, what is the shortest route from s to all other points (including s).
Idea: Regarding the limitation of unidirectional edges, we can understand this: the points connected by bidirectional edges must form a strong connected component. If a unidirectional edge exists in a strong connected component, it can be concluded that if "u-> "v", then it must be "v-> u", it can be deduced that unidirectional edges must only exist when connecting two strongly connected components, and can also be deduced. After the strong connected components are contracted, they are connected to unidirectional edges. It must be a directed acyclic graph, so the restriction given "gives a restriction for unidirectional edges: if u-> v holds, then v-> u must not hold." Completely established, so we analyze the nature of the graph Finished.
① It seems that the nature of this graph can directly run dijkstra, indeed, but the existence of negative weight edges is too complicated.
②Each strong connected component can be dijkstra, and the graph has a topological order. It is better to let the contraction point with the degree of 0 run dijkstra first, and then a unidirectional edge only affects the distance of one point of other strong connected components, and then follow the topological order To determine the order in which each strongly connected component runs dijkstra.
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <queue> 5 6 #define ll long long 7 #define pb push_back 8 #define fi first 9 #define se second 10 11 using namespace std; 12 13 const int N = 25000 + 10; 14 const int M = 50000 + 10; 15 const ll INF = 1e10; 16 struct Edge{ 17 int to, nxt, w; 18 }e[M << 2]; 19 struct node{ 20 int u, v, w; 21 }; 22 struct tmp{ 23 int now; 24 ll w; 25 bool friend operator<(const tmp& a, const tmp& b){ 26 return a.w > b.w; 27 } 28 }; 29 int head [N], scc [N], du [N], vis [N], ok [N]; 30 ll dis [N]; 31 vector <node> vp [N]; // unidirectional edge 32 vector < int > belong [N]; // Which scc 33 vector < int > mp [N]; // Save edge 34 priority_queue <tmp> pque; 35 int n, x, y, s, tot, col; 36 37 inline void add ( int u, int v, int w) { 38 e [tot] .to = v; e [tot] .nxt = head [u]; 39 e [tot] .w = w; head [u] = tot ++ ; 40 } 41 42 // Shrink point 43 void dfs ( int now) { 44 scc [now] = col; 45 belong [col] .pb (now) ; 46 for ( int o = head [now]; ~ o; o = e [o] .nxt) 47 if (! Scc [e [o] .to]) dfs (e [o] .to); 48 } 49 50 // Check if this point is valid 51 void check ( int now) { 52 ok [now] = 1 ; 53 for (auto to: mp [now]) 54 if (! ok [to]) check (to); 55 } 56 57 void dijkstra ( int ss) { 58 while (! pque.empty ()) pque.pop () ; 59 IF (s == SS) pque.push ({SS, DIS [SS]}); // FIG must start from the starting point s of 60 the else { 61 is // equivalent from a super source 62 is for ( auto it: belong [scc [ss]]) pque.push ({it, dis [it]}); 63 } 64 while (! pque.empty ()) { 65 int u =pque.top (). now; 66 pque.pop (); 67 if (vis [u]) continue ; 68 vis [u] = 1 ; 69 for ( int o = head [u]; ~ o; o = e [o] .nxt) { 70 if (dis [u] + e [o] .w < dis [e [o] .to]) { 71 dis [e [o] .to] = dis [u] + e [o] .w; 72 pque.push ({e [o] .to, dis [e [o] .to]}); 73 } 74 } 75 } 76 } 77 78 void top_sort () { 79 queue < int > que; 80 que.push (scc [s]); // The graph to be satisfied should be a topological graph starting from the connected graph of s 81 dijkstra (s); 82 while (! Que.empty ()) { 83 int inx = que.front (); 84 que.pop (); 85 for (auto it: vp [inx]) { 86 // A unidirectional edge affects the distance of a point 87 if (dis [it.u ] + it.w < dis [it.v]) { 88 dis [it.v] = dis [it.u] + it.w; 89 } 90 // Into degree 0, run dijkstra 91 if(--du[scc[it.v]] == 0){ 92 que.push(scc[it.v]); 93 dijkstra(it.v); 94 } 95 } 96 } 97 } 98 99 100 void solve(){ 101 scanf("%d%d%d%d", &n, &x, &y, &s); 102 for(int i = 1; i <= n; ++i) head[i] = -1; tot = 0; 103 for(int i = 1; i <= n; ++i) dis[i] = INF; dis[s] = 0; 104 int u, v, w; 105 for(int i = 1; i <= x; ++i){ 106 scanf("%d%d%d", &u, &v, &w); 107 add(u, v, w); add(v, u, w); 108 mp[u].pb(v); mp[v].pb(u); 109 } 110 111 vector<node > tmp; 112 for(int i = 1; i <= y; ++i){ 113 scanf("% d% d% d " , & u, & v, & w); 114 tmp.pb ({u, v, w}); 115 mp [u] .pb (v); 116 } 117 // The picture must be from The starting point s starts, so the traversal graph starting from s, the unreachable point is the unreachable point 118 // Check whether this point is valid 119 check (s); 120 // Contract point 121 for ( int i = 1 ; i <= n; ++ i) { 122 if (! scc [i] && ok [i]) { 123 ++ col; 124 dfs (i); 125 } 126 } 127 // Incoming statistics 128 for (auto x: tmp) { 129 if (ok [xu] && ok [xv]) { // valid point 130 vp [scc [xu]]. Pb (x); 131 ++ du [scc [xv]]; 132 } 133 } 134 top_sort (); // Topological order 135 for ( int i = 1 ; i <= n; ++ i) { 136 if (dis [i] == INF) printf ( " NO PATH \ n " ); 137 else printf ( " % lld \ n ", dis[i]); 138 } 139 } 140 141 int main(){ 142 143 solve(); 144 145 return 0; 146 } 147 148 /* 149 7 5 3 4 150 1 2 5 151 3 4 5 152 5 6 10 153 5 7 4 154 6 7 105 155 3 5 -100 156 4 6 -100 157 7 2 -100 158 */