Shortest Rehabilitation Scheme

Shortest Path Problem: FIG give you an (n points, m edges), at a distance from each edge. I asked the shortest distance from one point to another point.

 

Shortest focus on two algorithms: Dijkstra O (n ^ 2) and the SPFA O (n * m) (worst possible complexity) (in fact, almost impossible to reach the worst SPFA complexity)

 

Dijkstra:

 

Scope (limitations): There is no negative side right

 

Ideas:

We take the two sets, a set M as determined set point of the shortest distance, yet another set of N point set determining the shortest distance.

We all points of the set M to update the distance of a point in N, then set N from the smallest dot you can determine the distance to the minimum distance.

M initially set only a starting point, and gradually spread.

 

For the second line of thinking, we have to be proved:

After the distance M is set with the updated point of N points in the assumption, the minimum N can not be determined from the point o as the shortest path, then there must be a point p N so that M-> p-> o to o point shortest path, i.e., s (M-> p-> o) <s (M-> o). And s (M-> p)> s (M-> o) and s (p-> o)> 0 (the absence of a negative right side), so s (M-> p-> o) <s (M- > o) does not hold. The introduction of contradictions.

Therefore, the second row is proved.

 

Then we consider the code.

The most obvious approach is to set each add an element M x, x update by the shortest distance can be expanded to the point. Then traverse through all points, locate the set N and a minimum distance point, to add it to set M ...

So the cycle. Determining complexity of O (n ^ 2)

 

We can consider the optimization of a part of: traversing through all points, and the set N Locate the minimum distance point set M is added to it.

We just need to find a point, but we go through all the points, this is not no need to do?

We can use a small heap root, from the storage point to set N, then we find the complexity of each point of the minimum distance can be reduced to logn.

So the complexity of the Dijkstra reduces to O (m + nlogn) 

(In fact, non-optimized Dijkstra complexity is O (m + n ^ 2), because m <= n ^ 2, it is written as O (n ^ 2))

To template question: the Click here Wallpaper

Dijkstra:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 using namespace std ;
 7 const int N = 100000 + 10 ;
 8 const int M = 100000 + 10 ;
 9 const int INF = 0x7ffffff ;
10 
11 inline int read() {
12     int k = 0, f = 1 ; char c = getchar() ;
13     for( ; !isdigit(c) ; c = getchar())
14       if(c == '-') f = -1 ;
15     for( ; isdigit(c) ; c = getchar())
16       k = k*10 + c-'0' ;
17     return k*f ;
18 }
19 
20 struct Edge {
21     int to, nex, val ;
22 }e[N] ;
23 int n, m, cnt = 0 ;  int head[N], dis[N] ;  
24 bool vis[N] ;
25 
26 struct HeapNode {
27     int d, u ;
28     bool operator <  (const HeapNode& rhs) const {
29         return d > rhs.d ;
30     }
31 };
32 priority_queue<HeapNode>q ;
33 
34 inline void add_edge(int x,int y,int z) {
35     e[++cnt].nex = head[x] ; head[x] = cnt ; e[cnt].to = y ; e[cnt].val = z ;
36 }
37 
38 inline void djsk() {
39     dis[1] = 0 ;
40     for(int i=2;i<=n;i++) dis[i] = INF ;
41     memset(vis,0,sizeof(vis)) ;
42     q.push((HeapNode){0,1}) ;
43     while(!q.empty()) { 
44         HeapNode xx = q.top() ; q.pop() ;
45         int x = xx.u ;
46         if(vis[x]) continue ;  vis[x] = 1 ;
47         for(int i=head[x];i;i=e[i].nex) {
48             int y = e[i].to ;  if(vis[y]) continue ;
49             if(dis[y] > dis[x]+e[i].val) {
50                 dis[y] = dis[x] + e[i].val ;
51                 q.push((HeapNode){dis[y],y}) ;
52             }
53         }
54     }
55 }
56 
57 int main() {
58     n = read(), m = read() ;
59     for(int i=1;i<=m;i++) {
60         int x, y, z ;  x = read(), y = read(), z = read() ;
61         add_edge(x,y,z) ;
62     }
63     djsk() ;
64     printf("%d\n",dis[n]) ;
65     return 0 ;
66 }

 

SPFA:

Scope: negative weights ring absence (right side there may be negative) (negative weights can verify the existence of the drawing ring)

In fact SPFA is to optimize the Bellman-Ford algorithm, so we first introduce Bellman-Ford algorithm.

 

Bellman-Ford:

Ideas:

Bfs method using extended out layer by layer.

Each spreading layer, the spreading layer with a further layer below to update, and may be updated to point to the next layer is added to expand the collection thereof.

The first layer zero as a starting point.

Worst complexity: O (n * m) (in fact, difficult to achieve)

 

SPFA:

With a FIFO queue storing updatable point.

Each time a point removed from the first team x, with x other points to relaxation, to relax the encounter point x, x will be added to the tail.

Until the queue is empty.

A small optimization:

If dis [y] <dis [q.front ()] which will be added to the first team, instead of the tail.

SPFA Code (deque optimization):

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 using namespace std ;
 7 const int N = 100000 + 10 ;
 8 const int M = 100000 + 10 ; 
 9 const int INF = 0x7ffffff ;
10 
11 inline int read() {
12     int k = 0, f = 1 ; char c = getchar() ;
13     for( ; !isdigit(c) ; c = getchar())
14       if(c == '-') f = -1 ;
15     for( ; isdigit(c) ; c = getchar())
16       k = k*10 + c-'0' ;
17     return k*f ;
18 }
19 
20 struct Edge {
21     int to, nex, cos ;
22 }e[M] ;
23 
24 int n, m ;  int head[N], dis[N] ;
25 bool inq[N] ;
26 deque<int>q ;
27 
28 inline void add_edge(int x,int y,int z) {
29     static int cnt = 0 ;
30     e[++cnt].to = y, e[cnt].nex = head[x], head[x] = cnt, e[cnt].cos = z ;
31 }
32 
33 int main() {
34     int n, m ;
35     n = read(), m = read() ;
36     for(int i=1;i<=m;i++) {
37         int x = read(), y = read(), z = read() ;
38         add_edge(x,y,z) ;
39     }
40     for(int i=2;i<=n;i++) dis[i] = INF ;
41     q.push_back(1) ; dis[1] = 0 ;
42     while(!q.empty()) {
43         int x = q.front() ; q.pop_front() ; inq[x] = 0 ;
44         for(int i=head[x];i;i=e[i].nex) {
45             int y = e[i].to ;
46             if(dis[y] > dis[x]+e[i].cos) {
47                 dis[y] = dis[x]+e[i].cos ;
48                 if(!inq[y]) {
49                     if(!q.empty() && dis[y] < dis[q.front()]) q.push_front(y) ;
50                     else q.push_back(y) ;
51                     inq[y] = 1 ;
52                 }
53             }
54         }
55     }
56     printf("%d",dis[n]) ;
57     return 0 ;
58 }

 

Guess you like

Origin www.cnblogs.com/zub23333/p/11612965.html