Take note of the shortest path, record it to prevent forgetting! (2.25 update, more complete supplements, absolutely understandable!)


1. What is the shortest path?

There are actually many shortest path algorithms:

1. Dijkstra algorithm

2. Multi-source shortest path

I’m sorry, today we will first include the use of adjoining matrix and queue to implement the Dij algorithm, and other algorithms will be added later.······


2021.2.25 Update notes (update specific shortest notes and diagrams)

Today, many students said that they did not understand the shortest code list. This is indeed the case. When I was studying, I also saw it all night and I was confused. Today I added some easy-to-understand notes, hoping to help everyone avoid detours.


2. Algorithm introduction?

(Dijkstra was born in a family of intellectuals in Rotterdam, the Netherlands on May 11, 1930. He ranks third among four siblings. His father is a chemist and inventor and served as the president of the Dutch Chemical Society. His mother is a mathematician. He successfully designed and implemented an efficient algorithm for finding the shortest path between two locations with obstacles. This algorithm was named "Dijkstra's Algorithm". A very critical problem in robotics, the problem of motion path planning, is still widely used, and is considered a successful example of using the "greedy method" to design algorithms.)Insert picture description here
Diagram of the complete algorithm:
Insert picture description here
here we are The number of the definition diagram is:

1 2 3

4 5 6

7 8 9

Figure 1: Initialized graph with edge weights (time-consuming). (The graph here is a directed graph).

Figure 2: Determine the starting point, then walk to the point where you can go directly, and record the estimated value at this time: 2 6 9.

Figure 3: Find the point closest to the starting point, which is the point on the east side. At this time, we spend a weight of 2. Then we perform a relaxation operation. The weight cost from the starting point to the point southeast of it is 6 directly, but we have found a closer way to this point through the point just selected, so this time we say from the starting point The weight update value of the point to its southeast direction has changed from 6 to 5. At this time we have completed the first relaxation operation.

Figure 4: Still looking for the point closest to the starting point. Then slack we find that the cost weight from the starting point to the point southeast of it has changed from 5 to 4. At this time, we have completed the second slack.

The following method is the same as above: select the point v closest to the starting point. Then go through the point v to perform the relaxation operation. We found that we can relax the weight by increasing the complexity of the way to the destination (multi-turn), making the cost of the weight smaller.

Three, algorithm demonstration

Insert picture description here
First of all, the first step is to read all the data into the program, so what method should be used to store the path data?
Smart, you must have thought (maybe?), we can use the temporary matrix to achieve, that is to say, create a two-dimensional array.
When storing data, such as this question, the data given to you will be:

6 8
1 6 100
1 5 30 
4 6 10
1 3 10
2 3 5
3 4 50
5 4 20
5 6 60

Here 6 means 6 nodes, 8 means there will be 8 sets of data.
The first two of the following 8 sets of data are nodes, and the third is the weight.
We use the first two data as the horizontal and vertical coordinates of the map (two-dimensional data). , The third data is used as the stored value
(there is the difference between a directed graph and an undirected graph, if it is an undirected graph, we need two-way communication, the specific operation depends on the code)
In addition, remember to mark the data of i==j as 0 (the distance from itself to itself is 0)

In the second step, we declare a dis array to store the data of the distance from V1 to each vertex
(note here, the requirements are different for different topics, and the distance from other points to a certain point may be asked. This is flexible and flexible. )

Obviously, we can get the initial value of dis according to this question [0,INF,10,INF,30,100]

There are a few points here that may easily cause confusion. The first 0 refers to the distance from 1 to 1, which is obviously 0 (self to itself). You can think of this as a 1*6 matrix, represented by the ordinate. It is 1, 2, 3, 4, 5, 6, so that we can mark the distance from 1 directly to somewhere

Next, for the search operation, we need to find the shortest path from this dis. Obviously, the distance from 1 to 3 is 10. We send this distance to min. How flag=3 is used as the basis for the visit by vis later. (Vis[flag] = 1)

After that, go back to the graph we just created, we start to look for the flag row, look at the data in the flag row at this time, we can know that it is [10,5,0,50,0,0], and then the column starts from 1. Run a loop to 6, the judgment condition is (map[flag][j]+min<dis[j]), this condition is to judge whether the distance from 3 to other places plus the distance from v1 to v3 is less than The way from v1 to somewhere, if it is, it is obvious that dis[j] is overwritten with map[flag][j]+min<dis[j].
After running this loop, dis is also updated to [0 ,15,10,60,30,100]

In this way, the value of dis is constantly changing, and the final result we get is the shortest path from v1 to any point. Is it very simple?

Four, topic examples

1. Template questions (ZCMU-1624)

Link: ZCMU-1624 .
1624: The shortest path
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 368 Solved: 99
[Submit][Status][Web Board]
Description
There are n cities numbered 1—n, m roads , Tells you the length of each road, find the shortest path length given two points.

Input
T group data

The first row of each group of data has two positive integers n, m (n<=1000, m<=10000) respectively representing the number of cities and the number of roads, and the next m rows contain 3 integers a, b, c, indicates that there is a road of length c between city a and city b

Enter two integers x, y in the last line.

Output
outputs the shortest path from city x to city y. If there is no output, -1 is output.

Sample Input
2
3 2
1 2 2
2 3 3
1 3
4 2
1 2 3
1 3 2
1 4
Sample Output
5
-1

2. Implementation code

The code is as follows (example):

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
typedef long long ll;
int main(){
    
    
    int map[1005][1005],vis[1005],dis[1005];
    int T;
    cin >> T;
    int n,m;
    int a,b,h;
    while(T--){
    
    
        memset(vis, 0, sizeof vis);
        cin >> n >> m;
        //这里在初始化,就是将map的任意一点的距离都设置为无穷
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        map[i][j] = INF;
            
        
        for(int i =1;i<=n;i++)
        map[i][i] = 0;
        for(int i =1;i<=m;i++){
    
    
            cin >> a >> b >> h;
            if(h<map[a][b]){
    
    
            //双向导通
            map[a][b] = h;
            map[b][a] = h;
            }
        }

//        cout << endl;
//        for(int i=1;i<=n;i++){
    
    
//        for(int j=1;j<=n;j++)
//        cout << map[i][j] << " ";
//        cout << endl;
//        }


        int st,nd;
        scanf("%d %d",&st,&nd);
        for(int i =1;i<=n;i++)dis[i] = map[st][i];
        for(int i=1;i<n;i++){
    
    
            int min = INF;
            int flag = 0;
            for(int j=1;j<=n;j++){
    
    
            //这里就是查找最短的距离
                if(min>dis[j]&&!vis[j]){
    
    
                    flag = j;
                    min = dis[j];
                }
            }
            vis[flag] = 1;
            for(int j=1;j<=n;j++){
    
    
            //判断并且覆盖
                if(min+map[flag][j]<dis[j]&&!vis[j])
                    dis[j] = min + map[flag][j];
            }
        }
        int temp = dis[nd];
        if(temp!=INF)
            printf("%d\n",temp);
        else
            printf("-1\n");
//        for(int i=2;i<=n;i++)
//        cout << dis[i] << " ";
//        cout << endl;
    }
    return 0;
}

The following is an implementation using queue reprinted from someone else’s blog, posted here for later viewing:

void spfa()
{
	memset(dis, 0x3f, sizeof dis);
	dis[1] = 0; vis[1] = 1;//vis记录是否在队列里 
	queue<int> q;
	q.push(1);
	register int u, v;
	while(q.size())
	{
		u = q.front(); q.pop(); vis[u] = 0;
		for(int i = head[u]; ~i; i = e[i].nxt)//向外发散 
		{
			v = e[i].to;
			if(dis[u] + e[i].w < dis[v])
			{
				dis[v] = dis[u] + e[i].w;
				if(!vis[v]) q.push(v), vis[v] = 1; //不在队列中,那就放进去更新别的点 
			}
		}
	}
}

A few points to note:
1. Before solving the problem, it is necessary to judge whether this is a directed graph or an undirected graph. There is still a gap when reading the data.
2. It is worth noting that it may not be found In the case of the shortest path, that is, the distance from a place to a place is infinite (maxn), at this time, remember to output -1
. 3. There are several changes to this question. For example, the template question now outputs the shortest x to y Path, sometimes it may just ask you to output the shortest path from 1 to any city. Just know this.


to sum up

Tip: Here is a summary of the article: The
shortest path Dij algorithm occupies an important position in the ACM competition. It is an algorithm that needs to be memorized and used proficiently. If you are unfamiliar, you can just play a few template questions.

Guess you like

Origin blog.csdn.net/DAVID3A/article/details/114048575