2019 ICPC (Yinchuan)-Delivery Route (Strong Connected Component + Topological Sorting + dijkstra)

Delivery Route

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 */

 

 

 

 

Guess you like

Origin www.cnblogs.com/SSummerZzz/p/12655418.html