最短路Dijkstra(堆优化)
一、前置知识点:
1.
的使用
2.优先队列的使用
3.原
的
写法
二、其他
优化所在:当原来需要
的复杂度,从已经更新好最短路的点 更新 新的最短路时,可以用优先队列用
的方式直接取出 最短路的更新点。
点号和最短路是捆绑记录的,因此用到了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
多源最短路求法。
通过
可以求出任意两点的最短路。
但是时间复杂度太高导致 普适性很低,一般题目里不用。
用二维数组
表示 从点
到 点
距离。
注意初始化
经典例题: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]);