• C++之路进阶——优先队列优化最短路径算法(dijkstra)


    一般的dijkstra算法利用贪心的思想,每次找出最短边,然后优化到其他点的的距离,我们还采用贪心思路,但在寻找最短边进行优化,之前是双重for循环,现在我们用优先队列来实现。

    代码解释:

    //样例程序采用边表储存。   

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<cmath>
    #include<iostream>

    using namespace std;

    int head[100000]={0},next[200000]={0},aa[200000]={0},size,s,tt,m,n;


    struct bb
    {
    int x,y;
    }a[100000];//记录点的横纵坐标。
    double val[100000],dis[100000]={0};


    void add(int h,int t,double c)//建立边表。
    {
    size++;//对边进行重编号。
    next[size]=head[h];
    head[h]=size;
    aa[size]=t;
    val[size]=c;
    }

    void init()
    {
    scanf("%d",&n);
    for (int i=0;i<n;i++)
    {
    int u,v;
    double c;
    scanf("%d%d",&u,&v); //读入有边的两点。
    c=sqrt((a[u-1].x-a[v-1].x)*(a[u-1].x-a[v-1].x)+(a[u-1].y-a[v-1].y)*(a[u-1].y-a[v-1].y));//用数学公式求出两点间距离。
    add(u,v,c);//建立由u到v的边,权值为c;
    add(v,u,c);//若图为有向图,则省略该语句。
    }
    scanf("%d%d",&s,&tt); //读入所求的由s到tt的距离。目标。
    }

    void initint()//存下点的坐标。
    {
    scanf("%d",&m);
    for (int i=0;i<m;i++)
    scanf("%d%d",&a[i].x,&a[i].y);
    }

    struct ss//定义优先队列的自定义结构体。
    {
    int x;
    double y;
    ss(){}//定义构造函数。
    ss(int xx,double yy)//重载该函数。
    {
    x=xx;
    y=yy;
    }


    bool operator<(const ss& b)const//重载<运算符(因为我们要找最小值,而优先队列默认为大根堆)。
    {
    return y>b.y;
    }
    };

    void dij()//dijkstra算法
    {
    priority_queue<ss>que;//定义优先队列,不懂看“C++之路启航——标准模板库(queue)”
    que.push(ss(s,0));//把起点压入队列中。
    for (int i=0;i<=m;i++)//
    dis[i]=100000000;
    dis[s]=0;// 初始操作。
    while (!que.empty())
    {
    ss op=que.top();//取出最小值。op.x为点的编号,op.y为从起点到该点的距离。
    que.pop();
    if (op.y>dis[op.x]) continue;//一步优化。
    for (int i=head[op.x];i!=0;i=next[i]) //遍历与该点相连的边。
    {
    int j=aa[i];
    if (dis[j]>dis[op.x]+val[i])//找到能够更新的,并且压入队列中。
    {
    dis[j]=dis[op.x]+val[i];
    que.push(ss(j,dis[j]));
    }
    }
    }
    printf("%.2f",dis[tt]);//输出;
    return;
    }

    int main()
    {
    initint();
    init();
    dij();
    return 0;
    }

  • 相关阅读:
    Java基础(十四)——API(Calendar类、System类、StringBuilder类、包装类)
    异常
    Java基础(十三)——权限修饰符和内部类
    知识点总结
    Java基础(十二)— —多态
    Java基础(十一)— —继承、抽象类和接口
    java基础(十)——继承
    小程序外部向组件内部传递externalClasses -- 传入样式wxss
    小程序组件交互 -- 传入js
    promise封装小程序的请求类(request,清爽易懂)
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5079583.html
Copyright © 2020-2023  润新知