Monotonic queue + forward star's dijkstra algorithm, super detailed ~~

Graph theory-shortest path-detailed explanation of dijkstra algorithm

Ideas

Using the forward star storage graph, use the priority queue to find the unvisited shortest path adjacent to the previous point. Starting from the starting point, find the shortest path e connected to the starting point s again and again, dis[e]=min(dis[e],dis[s]+w[e][s]), if this point is updated and before Have not been added to the queue before, then add him to the queue. Until the queue is empty.

example

Luogu P4779
topic description:
Given a graph with nn points and mm directed edges with non-negative weights, please calculate the distance from ss to each point. The data guarantees that you can start from ss to any point.

Input format: The
first line is three positive integers n, m, s. From the second line, the mm line, each line has three non-negative integers ui, vi, wi, indicating that there is a directed edge with weight wi from ui to vi.

Output format :
output a line of nn space-separated non-negative integers, representing the distance from ss to each point.

dijkstra code

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5+5;
const int N = 1e5+5;

int n,m,s;
int vis[N],ru[N]={
    
    0};


struct ling{
    
      //前向星的结构体
	int e,w,next; 
	//e表示这条路终点,w表示路的长度,next表示上一个连接这条路的起点的终点
}dege[M];
int cnt=1,head[M];

void add(int u,int v,int w){
    
      //前向星
	dege[cnt].e=v;
	dege[cnt].w=w;
	dege[cnt].next=head[u];
	head[u]=cnt++;
}

struct node{
    
     
	int u,d;
	//u表示这条路的起点,d表示这个起点到初始点的距离
	node(int u,int d):u(u),d(d){
    
    }
	bool operator < (const node &a)const{
    
    
		return d>a.d; //最小堆
	}
};
priority_queue<node> q;

void dijk(int s){
    
    
	memset(ru,0,sizeof(ru));
	memset(vis,0x3f,sizeof(vis));
	vis[s]=0;
	q.push(node(s,vis[s]));
	while(!q.empty()){
    
    
		node t = q.top();q.pop();
		int u = t.u;
		int d = t.d;
	
		if(ru[u]) continue ; 
		//我第一次写成return,一直过不了……
		//应该是找不到就找下一条路
		ru[u]=1;
		for(int i=head[u];i>0;i=dege[i].next){
    
    
			int v = dege[i].e;
			int w = dege[i].w;
			
			if(vis[v]>d+w){
    
    
				vis[v]=d+w;
				q.push(node(v,vis[v]));
			}
		}
	}
}

int main(){
    
    
	ios::sync_with_stdio(false);
	memset(head,-1,sizeof(head));
	cin>>n>>m>>s;
	while(m--){
    
    
		int u,v,w;
		cin>>u>>v>>w;
		add(u,v,w);
	}
	dijk(s);
	for(int i=1;i<=n;++i){
    
    
		cout<<vis[i]<<" ";
	}
} 

to sum up

· The time complexity of dijkstra is (mlogm), which is relatively fast.
·But he can't judge the negative weight graph, please pay attention when using it!

Guess you like

Origin blog.csdn.net/qq_45758578/article/details/108649733