【算法模板】Dijkstra 队列优化版本,手敲留念~

本文介绍了一种基于Dijkstra算法的队列优化实现方法,并提供了详细的C++代码示例。该算法通过使用优先队列来提高查找最短路径的效率,适用于解决带权图中的单源最短路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

额,大一暑假写的Dijkstra 队列优化版本,还是比较干净的,翻出来存起来以后备用。

 

#define inf 9999
#define INF 0x3f3f3f3f
#define loop(x,y,z) for(x=y;x<z;x++)
//下标自1始

int n,m,s,g;                 //s 为起点 g 为终点
int book[inf],dis[inf];      //book为标记,一个点作为中转点只能走一次
                            //dis 为起点到此点距离
int father[inf];             //记录路径:每一个点来自于上一个节点的编号
struct Node                  //存储边
{
    int to,w;
    Node(int i,int j)
    {
        to=i;w=j;
    }
    bool operator< (const Node& i)const
    {
        return w>i.w;
    }
};
vector<Node>edge[inf];       //edge 来存储每一个邻接边
priority_queue<Node>q;       //优先队列用来取元素

void init()
{
    int i;
    memset(book,0,sizeof book);
    loop(i,1,n+1)edge[i].clear();
    while(!q.empty())q.pop();
    loop(i,1,n+1)
        dis[i]=INF;
    dis[s]=0;
}
void Dijkstra()
{
    int i,j,k;
    q.push(Node(s,0));               //压入起点
    while(!q.empty())
    {
        Node t=q.top();
        q.pop();
        int u=t.to;
        if(book[u])continue;       //取出距离起点最小点(Dijkstra思想),取过就吐掉
        book[u]=1;
        int len=edge[u].size();
        loop(i,0,len)                //对中转点每一条邻接边 松弛
        {
            Node& e=edge[u][i];
            if(dis[e.to]>dis[u]+e.w)
            {
                dis[e.to]=dis[u]+e.w;
                father[e.to]=u;               //松弛成功更新路径
                q.push(Node(e.to,dis[e.to]));      //压入此点时,压入的是节点号,以及节点到起点的距离 dis
            }
        }
    }
}
int main()
{
    int i,j,k;
    scanf("%d%d",&m,&n);
    s=n;g=1;                                  //起点和终点别忘记修改
    init();
    while(m--)
    {
        scanf("%d%d%d",&i,&j,&k);
        edge[i].push_back(Node(j,k));         //这个方法即使有重边也不用修改
        edge[j].push_back(Node(i,k));
    }
    Dijkstra();
    printf("%d\n",dis[g]);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值