zoukankan      html  css  js  c++  java
  • 模板——dijkstra单源最短路

    传送门:https://www.luogu.com.cn/problem/P4779

    dijstra 算法用于对单源最短路的求解问题,运用堆优化后,可以在O((({n}+{m}) imeslog_2{n}))的复杂度内解决两点之间的最短路问题

    实现方法:

    • dijstra 算法基于贪心的思想实现
    • 对于一个未更新的权值最小的节点x,将其标记为已走过,对于该节点x的所有出边y,边权为z,若存在 d[y]>d[x]+z,则令d[y]=d[x]+z,进行更新
    • 重复上述步骤,直至所有的节点均被标记

    dijstra不适合用于存在负边权的图中

    dijstra运用堆优化,可以有效地避免对其他无关的边进行的冗余运算,可以有效地提升其运算复杂度

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<queue>
    #define ll long long
    using namespace std;
    
    const ll maxm=2e5+10;
    int n,m,s,tot;
    int edge[maxm],ver[maxm],next[maxm],head[maxm],v[maxm],dis[maxm];
    priority_queue<pair<int,int> > q;
    
    inline void add(const int u,const int v,const int w)\邻接表存图,可以用vector代替
    {
    	ver[++tot]=v;
    	edge[tot]=w;
    	next[tot]=head[u];
    	head[u]=tot;
    }
    
    inline void dij(int x)
    {
    	memset(dis,0x3f,sizeof(dis));\初始化边权值
    	memset(v,0,sizeof(v));
    	dis[x]=0;
    	q.push(make_pair(0,1));\优先队列实现堆优化dijstra
    	while(q.size()!=0)
    	{
    		int x=q.top().second;
    		q.pop();
    		if(v[x]==1) continue;
    		v[x]=1;
    		for(int i=head[x];i;i=next[i])
    		{
    			int y=ver[i];
    			int z=edge[i];
    			
    			if(dis[y]>dis[x]+z)
    			{
    				dis[y]=dis[x]+z;
    				q.push(make_pair(-dis[y],y));
    			}
    		}
    	}
    }
    
    int main(void)
    {
    	scanf("%d%d%d",&n,&m,&s);
    	
    	for(int x,y,z;m;m--)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		add(x,y,z);
    	}
    		
    	dij(s);
    	
    	for(int i=1;i<=n;i++)
    	{
    		printf("%d ",dis[i]);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    第十一章关联容器
    第十章泛型算法
    第九章
    第八章
    阅读记录
    java.lang.Class阅读笔记
    java.time包阅读笔记
    CLion运行多个main函数
    c++中lower_bound和upper_bound中的comp参数
    如何写dfs
  • 原文地址:https://www.cnblogs.com/jd1412/p/13282446.html
Copyright © 2011-2022 走看看