0
点赞
收藏
分享

微信扫一扫

最短路-Dijkstra

墨春 2022-01-31 阅读 51

最短路——Dijkstra

文章目录

Dijkstra

算法描述

  1. 设置出发顶点为v,顶点集合V{v1,v2,vi…vn},v到V中各顶点的距离构成距离集合dis,dis{d1,d2,di…dn},Dis集合记录着v到图中各顶点的距离(到自身可以看作0,v到vi距离对应为di,初始时,设置di=oo)
  2. 从dis中选择值最小的di并移出dis集合,同时移出V集合中对应的顶点vi,此时的v到vi即为最短路径
  3. 更新dis集合,更新规则为:比较v到V集合中顶点的距离值,与v通过vi到V集合中顶点的距离值,保留值较小的一个
  4. 重复执行2、3步骤,直到编历完所有的点

模板

1.基于邻接表的Dijkstra

void Dijkstra(int s){
	memset(dist,INF,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[s]=0;
	for(int k=0;k<n;k++){
		int u,mind=INF;
		for(int i=1;i<=n;i++){
			if(dist[i]<mind && !vis[i]){
				mind=dist[i];
				u=i;
			}
		}
		vis[u]=1;
		for(int i=head[u];i;i=edge[i].next_edge){
			int v=edge[i].to,w=edge[i].w;
			if(dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
			}
		}
	}
}

2.优先队列优化的Dijkstra

struct node{
	int id,dis;
	node(){}
	node(int idd,int diss):id(idd),dis(diss){}
	bool operator <(const node &a) const{
		return a.dis<dis;
	}
};
void Dijkstra(){
	memset(dist,INF,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[1]=0;
	priority_queue<node> q;
	q.push(node(1,dist[1]));
	while(!q.empty()){
		node t=q.top();
		q.pop();
		int u=t.id;
		if(vis[u])	continue;
		for(int i=head[u];i;i=edge[i].next_edge){
			int v=edge[i].to,w=edge[i].w;
			if(dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
				q.push(node(v,dist[v]));
			}
		}
	}
}

例题

POJ-2387

POJ2387 Til the Cows Come Home

题目描述

具体代码

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1002,maxe=4002;
int n,m,num_edge;
int dist[maxn],head[maxn];
bool vis[maxn];
struct E{
	int to,next_edge,w;
}edge[maxe];
void add_edge(int u,int v,int w){
	edge[++num_edge].w=w;
	edge[num_edge].to=v;
	edge[num_edge].next_edge=head[u];
	head[u]=num_edge;
}
void Dijkstra(int s){
	memset(dist,INF,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[s]=0;
	for(int k=0;k<n;k++){
		int u,mind=INF;
		for(int i=1;i<=n;i++){
			if(dist[i]<mind && !vis[i]){
				mind=dist[i];
				u=i;
			}
		}
		vis[u]=1;
		for(int i=head[u];i;i=edge[i].next_edge){
			int v=edge[i].to,w=edge[i].w;
			if(dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
			}
		}
	}
}
int main(){
	scanf("%d%d",&m,&n);
	for(int i=0;i<m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add_edge(x,y,z);
		add_edge(y,x,z);
	}
	Dijkstra(1);
	printf("%d\n",dist[n]);
	return 0;
}

POJ-3159

[POJ-3159 Candies ]https://vjudge.csgrandeur.cn/problem/POJ-3159)

题目描述

具体代码

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=3e4+2;
const int M=150002;
int n,m,num_edge;
int head[maxn],dist[maxn];
bool vis[maxn];
struct Edge{
	int to,w,next_edge;
}edge[M];
struct node{
	int id,dis;
	node(){}
	node(int idd,int diss):id(idd),dis(diss){}
	bool operator <(const node &a) const{
		return a.dis<dis;
	}
};

void add_edge(int u,int v,int w){
	edge[++num_edge].to=v;
	edge[num_edge].w=w;
	edge[num_edge].next_edge=head[u];
	head[u]=num_edge;
}
void Dijkstra(){
	memset(dist,INF,sizeof(dist));
	memset(vis,0,sizeof(vis));
	dist[1]=0;
	priority_queue<node> q;
	q.push(node(1,dist[1]));
	while(!q.empty()){
		node t=q.top();
		q.pop();
		int u=t.id;
		if(vis[u])	continue;
		for(int i=head[u];i;i=edge[i].next_edge){
			int v=edge[i].to,w=edge[i].w;
			if(dist[v]>dist[u]+w){
				dist[v]=dist[u]+w;
				q.push(node(v,dist[v]));
			}
		}
	}
}
int main(){
	while(~scanf("%d%d",&n,&m)){
		num_edge=0;
		memset(head,0,sizeof(head));
		for(int i=1;i<=m;i++){
			edge[i].next_edge=0;
		} 
		for(int i=0;i<m;i++){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			add_edge(u,v,w);
		}
		Dijkstra();
		printf("%d\n",dist[n]);
	}
	return 0;
}
set(head,0,sizeof(head));
		for(int i=1;i<=m;i++){
			edge[i].next_edge=0;
		} 
		for(int i=0;i<m;i++){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			add_edge(u,v,w);
		}
		Dijkstra();
		printf("%d\n",dist[n]);
	}
	return 0;
}
举报

相关推荐

0 条评论