很早之前就已经了解过最短路算法了,这里写几个优化后的模板以便复习
Dijkstra堆优化+链式前向星
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5;
const int inf = 0x3f3f3f3f;
int head[maxn],cnt,dis[maxn];//head[i]记录点i最后出现的位置
int n,m;
bool vis[maxn];
struct edge{
int to,w,next;
}e[maxn];
struct node{
int u,w;
node(int uu,int ww):u(uu),w(ww){}
bool operator <(const node &r)const{
return w > r.w;
}
};
void add_edge(int u,int v,int w){
e[cnt].next = head[u];
e[cnt].to = v;
e[cnt].w = w;
head[u] = cnt++;
}
//链式前向星
void dij(int st ,int ed){
memset(dis,inf,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[st] = 0;
for(int i = 1 ; i <= n ; i++){
int u = -1,minn = inf;
for(int j = 1 ; j <= n ; j++){
if(vis[j] == false && vis[j] < minn){
minn = vis[j];
u = j;
}
}
if(u == -1) break;
vis[u] = true;
for(int j = head[u] ; j != -1 ; j = e[j].next){
int v = e[j].to,w = e[j].w;
if(vis[v] == false && dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
}
}
}
if(dis[ed] == inf) cout << "-1" << endl;
else cout << dis[ed] << endl;
}
//链式前向星+堆优化
void dij2(int st,int ed){
memset(vis,false,sizeof(vis));
memset(dis,inf,sizeof(dis));
dis[st] = 0;
priority_queue<node>pque;
pque.push(node(st,0));
while(!pque.empty()){
node t = pque.top();
pque.pop();
int u = t.u;
if(vis[u])continue;
vis[u] = true;
for(int i = head[u] ; i != -1 ; i = e[i].next){
int v = e[i].to,w = e[i].w;
if(vis[v] == false && dis[v] > dis[u] + w){
dis[v] = dis[u]+w;
pque.push(node(v,dis[v]));
}
}
}
if(dis[ed] != inf) cout << dis[ed] << endl;
else cout << "-1" << endl;
}
int main(){
memset(head,-1,sizeof(head));
cin >> n >> m;
for(int i = 0 ; i < m ; i++){
int u,v,w;
cin >> u >> v >> w;
add_edge(u,v,w);
add_edge(v,u,w);
}
dij(1,n);
dij2(1,n);
return 0;
}
Spfa队列优化+链式前向星
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4+5;
const int inf = 0x3f3f3f3f;
int cnt,n,m,head[maxn],dis[maxn];
bool vis[maxn];
struct edge{
int to,w,next;
}e[maxn];
void add_edge(int u,int v,int w){
e[cnt].next = head[u];
e[cnt].w = w;
e[cnt].to = v;
head[u] = cnt++;
}
void spfa(int st,int ed){
memset(vis,false,sizeof(vis));
memset(dis,inf,sizeof(dis));
queue<int>q;
q.push(st);
dis[st] = 0,vis[st] = true;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u] ; i != -1 ; i = e[i].next){
int v = e[i].to,w = e[i].w;
if(dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
if(!vis[v]){
q.push(v);
vis[u] = true;
}
}
}
vis[u] = false;
}
cout << dis[ed] << endl;
}
int main(){
memset(head,-1,sizeof(head));
cin >> n >> m;
for(int i = 0 ; i < m ; i++){
int u,v,w;
cin >> u >> v >> w;
add_edge(u,v,w);
add_edge(v,u,w);
}
spfa(1,n);
return 0;
}
Floyed算法
暴力算法,三重for循环,最外层表示转折点,次外层表示起点,内层表示终点
I'm so cute. Please give me money.
- 本文链接:http://yoursite.com/2020/08/04/%E6%9C%80%E7%9F%AD%E8%B7%AF%E7%9A%84%E5%90%84%E7%A7%8D%E4%BC%98%E5%8C%96/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。
若没有本文 Issue,您可以使用 Comment 模版新建。
GitHub IssuesGitHub Discussions