堆优化dijkstra的两种写法
例题:
https://www.acwing.com/problem/content/description/1131/
1、仅用dis数组记录,出队时记录最小距离(可能会导致重复入队)

#include<bits/stdc++.h> #define fore(x,y,z) for(LL x=(y);x<=(z);x++) #define forn(x,y,z) for(LL x=(y);x<(z);x++) #define rofe(x,y,z) for(LL x=(y);x>=(z);x--) #define rofn(x,y,z) for(LL x=(y);x>(z);x--) #define pb push_back #define all(x) (x).begin(),(x).end() #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef pair<LL,LL> PLL; int n,m,s,t; vector<int> adj[3000]; vector<int> cost[3000]; int dis[3000]; void Dijkstra() { memset(dis,0x3f,sizeof(dis)); priority_queue<PII,vector<PII>,greater<PII>> que; que.push({0,s}); while(que.size()) { PII dis_u=que.top(); que.pop(); if(dis[dis_u.se]<=dis_u.fi) continue; dis[dis_u.se]=dis_u.fi; if(dis_u.se==t) break; int sz=adj[dis_u.se].size(); for(int i=0;i<sz;i++) { if(dis_u.fi+cost[dis_u.se][i]<dis[adj[dis_u.se][i]]) que.push({dis_u.fi+cost[dis_u.se][i],adj[dis_u.se][i]}); } } } void YD() { cin>>n>>m>>s>>t; while(m--) { int a,b,c;cin>>a>>b>>c; adj[a].push_back(b); cost[a].push_back(c); adj[b].push_back(a); cost[b].push_back(c); } Dijkstra(); cout<<dis[t]<<endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T=1; //cin >> T; while (T--) { YD(); } return 0; }
2、用dis和vis数组记录,入队时更新最小距离,出队时更新vis数组(必须使用vis的原因是,无法直接用dis数组进行判断,可能有多个相同的最小dis造成重复更新)

#include<bits/stdc++.h> #define fore(x,y,z) for(LL x=(y);x<=(z);x++) #define forn(x,y,z) for(LL x=(y);x<(z);x++) #define rofe(x,y,z) for(LL x=(y);x>=(z);x--) #define rofn(x,y,z) for(LL x=(y);x>(z);x--) #define pb push_back #define all(x) (x).begin(),(x).end() #define fi first #define se second using namespace std; typedef long long LL; typedef pair<int,int> PII; typedef pair<LL,LL> PLL; int n,m,s,t; vector<int> adj[3000]; vector<int> cost[3000]; int dis[3000]; bool vis[3000]; void Dijkstra() { memset(dis,0x3f,sizeof(dis)); priority_queue<PII,vector<PII>,greater<PII>> que; que.push({0,s}); dis[s]=0; while(que.size()) { PII dis_u=que.top(); que.pop(); if(vis[dis_u.se]) continue; vis[dis_u.se]=true; if(dis_u.se==t) break; int sz=adj[dis_u.se].size(); for(int i=0;i<sz;i++) { if(dis_u.fi+cost[dis_u.se][i]<dis[adj[dis_u.se][i]]) { dis[adj[dis_u.se][i]]=dis_u.fi+cost[dis_u.se][i]; que.push({dis_u.fi+cost[dis_u.se][i],adj[dis_u.se][i]}); } } } } void YD() { cin>>n>>m>>s>>t; while(m--) { int a,b,c;cin>>a>>b>>c; adj[a].push_back(b); cost[a].push_back(c); adj[b].push_back(a); cost[b].push_back(c); } Dijkstra(); cout<<dis[t]<<endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T=1; //cin >> T; while (T--) { YD(); } return 0; }
疑似第二种更快,第一种更好写
第一种TLE,第二种过的例题:
https://www.acwing.com/problem/content/1129/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人