堆优化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;
}
View Code
复制代码

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;
}
View Code
复制代码

 疑似第二种更快,第一种更好写

第一种TLE,第二种过的例题:

https://www.acwing.com/problem/content/1129/

posted @   80k  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示