图论最短路:迪杰斯特拉Dijkstra算法及堆优化

今天讲的算法出自这个人:

图论最短路:迪杰斯特拉Dijkstra算法及堆优化_第1张图片

好帅呀!

dijkstra算法用于单源最短路,就是在一张图中从一个点(一般是1)到所有点的最短路,n代表点数,m代表边数,朴素的dijkstra算法复杂度是 O O O(n2),堆优化后可以达到 O O O((n+m)×logn),最重要的是它不会像SPFA一样被卡掉,所以皮实好用呀!(关于SPFA,他死了)
dijkstra算法的主要思想是贪心,先把1加入点集,然后在所有与点集的连边中找到最短的,更新dis数组(表示当前最短的距离),然后把那条边连向的点加入点集,再进行过程,直到所有的点都在点集中时dis数组就是最后的答案
emmmm,之前说过了,这么算的话算法的复杂度是n方的,我们还可以堆优化,在之前的过程中,我们需要在所有连边中找到最短的,这个可以用堆优化来完成。
所以奉上代码:

#include
using namespace std;
const int MAXN=1e5+10,MAXM=2e5+10;
int n,m,s;
int x,y,c;
int head[MAXN],d[MAXN];
bool v[MAXN];
struct Edge{
	int next,to,dat;
}edge[MAXM];
int tot;
priority_queue<pair<int,int> > q;
void addedge(int x,int y,int c){
	edge[++tot].to=y;
	edge[tot].dat=c;
	edge[tot].next=head[x];
	head[x]=tot;
} 
void dijkstra(){
	memset(d,0x3f,sizeof(d));
	memset(v,0,sizeof(v));
	d[s]=0;
	q.push(make_pair(0,s));
	while(!q.empty()){
		int x=q.top().second;
		q.pop();
		if(v[x]) continue;
		v[x]=true;
		for(int i=head[x];i;i=edge[i].next){
			int y=edge[i].to,z=edge[i].dat;
			if(d[y]>d[x]+z){
				d[y]=d[x]+z;
				q.push(make_pair(-d[y],y));
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&c);
		addedge(x,y,c);
	}
	dijkstra();
	for(int i=1;i<=n;i++) printf("%d ",d[i]);
	return 0;
}

然后学会这个算法后可以a这道题了

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