【图论】Dijkstra算法(优化版)

注意:Dijkstra不能处理负边权问题!!!

一.基础版

请见上篇文章(23条消息) 【图论】Dijkstra算法(基础版)_SY奇星的博客-CSDN博客


二.优化策略 

关于存图,我们可以使用链式前向星进行优化。在贪心找最小边搭桥的时候,我们可以使用优先队列进行优化。


三.题目

P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

详细我是真不想写了,代码中的注释也写的比较明白了,您也可以见这道题的题解,那边也有较详细的讲解。 

四.【AC】代码

#include
#define maxn 500010
using namespace std;
int n,m,s; //点,边,起点 
int dis[maxn],vis[maxn]; //同基础版
//链式前向星 
struct Edge{
	int u,v,w,next;
}edge[maxn<<1]; //要乘2,以防为双边,即无向边 
int head[maxn];
//优先队列 
struct node{
	int u,w;
	bool operator < (const node &x) const{ //运算符重载 
		return x.wv是从大到小; 
	}
};
int tot=0; //加边计数器 
inline void add(int u,int v,int w){
	edge[++tot]=(Edge){u,v,w,head[u]};
	head[u]=tot;
}
void dijkstra(){
	for(int i=1;i<=n;i++) dis[i]=0x7fffffff; //初始化数组 
	dis[s]=0;
	priority_queue q;
	q.push((node){s,0});  //第一个点入队,进行搭桥 
	while(!q.empty()){
		node temp=q.top();q.pop();  //相当于int u=q.top().u 
		int u=temp.u; //搭桥点 
		if(vis[u]) continue;  //用过就不再用了 
		vis[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w;
			if(dis[u]+w>n>>m>>s;
	for(int i=1;i<=m;i++){
		int u,v,w;cin>>u>>v>>w;add(u,v,w);
	}
	//调用算法 
	dijkstra();
	//输出答案 
	for(int i=1;i<=n;i++) cout<

你可能感兴趣的:(图论,算法,图论)