刘汝佳 迪杰斯特拉 优先队列优化

来源:互联网 发布:ipad福利软件 编辑:程序博客网 时间:2024/06/18 05:42
const int inf=0x3f3f3f3f;struct Edge{    int from,to,dist;///dist为起点到这个边终点的最小距离    Edge(int u,int v,int d):from(u),to(v),dist(d){}};struct Dijkstra{    int n,m;    vector<Edge> edges;///存边的信息    vector<int > G[maxn];///存边的编号    bool done[maxn];   ///是否执行过标记    int d[maxn];    ///s到各点距离    int p[maxn];    ///点i的前驱    void init(n){        this->n=n;///赋值全局变量的n        for(int i=0;i<n;i++) G[i].clear();        edges.clear();    }    void AddEdge(int from,int to,int dist){///如果是无向图则每条边调用两次        edges.push_back(Edge(from,to,dist));        m=edges.size();        G[from].push_back(m-1);    }    struct HeapNode{        int d,u;        bool operator < (const HeapNode& rhs) const{///重载小于运算符            return rhs.d<d;        }    };    void dijkstra(int s){        priority_queue<HeapNode> Q;///优先队列        for(int i=0;i<n;i++) d[i]=inf;///开始时初始化所有距离为无穷大        d[s]=0;///起点初始化为0        memset(done,0,sizeof(done));///初始化:全部点都没有处理过        Q.push_back(HeapNode{0,s});///d=0,u=s;        while(!Q.empty()){            HeapNode x=Q.top();Q.pop();            int u=x.u;            if(done(u)) continue;            done[u]=true;            for(int i=0;i<G[u].size();i++){                Edge& e=edges[G[u][i]];///找到u的直接邻接边                if(d[e.to]>d[u]+e.dist){///边更小                    d[e.to]=d[u]+e.dist;///存入更小的边                    p[e.to]=G[u][i];///把G[u][i]设为e.to的直接前驱                    Q.push((HeapNode){d[e.to],e.to});///再输入下一个点,注意这里的d值比前面的入队的都大,所以会在之前入队的后面,不会影响队列顺序。                }            }        }    }};