【模版】最短路Dijkstra + Floyed


最短路Dijkstra(堆优化)


一、前置知识点:
1. p a i r pair 的使用
2.优先队列的使用
3.原 d i j k s t r a dijkstra n 2 n^2 写法
二、其他
优化所在:当原来需要 O ( n ) O(n) 的复杂度,从已经更新好最短路的点 更新 新的最短路时,可以用优先队列用 O ( log 2 n ) O(\log_2{n}) 的方式直接取出 最短路的更新点。
点号和最短路是捆绑记录的,因此用到了pair记录。
对最短路的排序是默认为第一关键字的,点号为第二关键字。
三、例题
luogu P4779 Dijkstra模版
luogu P1821 银牛派对

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
typedef pair<int,int> pii;
priority_queue <pii,vector<pii>,greater<pii> > q; 
int n,m,s;
int dis[2020200],head[1020200];
bool vis[2020200];
struct next_list
{
	int to,nxt,val;
}e[2020200];

void add_edge(int u, int v, int val)
{
	e[++head[0]].to = v;
	e[head[0]].val = val;
	e[head[0]].nxt = head[u];
	head[u] = head[0];
}
int main()
{
	scanf("%d%d%d",&n,&m,&s);
	for(int i = 1; i <= m; i++)
	{
		int u,v,val;
		scanf("%d%d%d",&u,&v,&val);
		add_edge(u, v, val);
	}
	for(int i = 0; i <= n; i++)
		dis[i] = 2147483647;
	dis[s] = 0;
	q.push(make_pair(dis[s],s));
	while(!q.empty())
	{
		int x = q.top().second;
		q.pop();
		if(vis[x])	continue;
		vis[x] = 1;
		for(int i = head[x]; i; i = e[i].nxt)
			if(dis[x] + e[i].val < dis[e[i].to])
			{
				dis[e[i].to] = dis[x] + e[i].val;
				q.push(make_pair(dis[e[i].to],e[i].to));
			}
	}
	for(int i = 1; i <= n; i++)
		printf("%d ",dis[i]);
	return 0;
}

最短路Floyed


多源最短路求法。
通过 O ( n 3 ) O(n^3) 可以求出任意两点的最短路。
但是时间复杂度太高导致 普适性很低,一般题目里不用。

用二维数组 d i s [ i ] [ j ] dis[i][j] 表示 从点 i i 到 点 j j 距离。
注意初始化 d i s [ i ] [ i ] = 0 dis[i][i]=0

经典例题:luoguP1119 灾后重建

for(int i = 1; i <= n; i++)
	for(int j = 1; j <= n; j++)
		if(i == j)	dis[i][j] = 0;
		else	dis[i][j] = 2e9;
		
读入数据更新 dis数组

for(int k = 1; k <= n; k++)
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
			dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);
发布了10 篇原创文章 · 获赞 10 · 访问量 680

猜你喜欢

转载自blog.csdn.net/LH_991215/article/details/103529344