zoukankan      html  css  js  c++  java
  • Dijkstra(堆优)模板

    Dijkstra最短路算法

    由于CCF卡死Shortest Path Fake Algorithm,我们简短的SPFA用不了了,于是背下Dijkstra堆优化的板子是很重要的

    模板(手打堆)

    #include<cstdio>
    #include<cstring> 
    #define N 100010//点数 
    #define M 200010//边数 
    #define inf 0x3f3f3f3f//正无穷 
    using namespace std;
    int heap[N],dis[N],pos[N];
    //heap为堆、dis[i]表示源点到i的距离
    //pos[i]表示i号点在堆中的位置、即heap[pos[i]]=i; 
    int frt[N],nxt[M<<1],v[M<<1],w[M<<1];
    //邻接链表存图 
    int n,m,tot,p;
    inline int swap(int &x,int &y)
    {int t=x;x=y;y=t;}//手写的交换函数 
    inline int read()//快读 
    {
        int x=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        ch=getchar();
        while(ch>='0'&&ch<='9')
        {
            x=(x<<1)+(x<<3)+ch-'0';
            ch=getchar();
        }
        return x;
    }
    void write(int x)//快输 
    {
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    inline void add(int x,int y,int z)
    {
        v[++tot]=y;w[tot]=z;
        nxt[tot]=frt[x];frt[x]=tot;
    }//加一条x到y长度为z的边 
    inline void siftdown(int x)
    {//维护堆,将堆中第i号点往下移 
        int i,j,k;
        while(x<=n>>1)
        {
            i=heap[x];j=heap[x<<1];k=heap[x<<1|1];
            if(x<<1|1<=n)//如果当前点有两个儿子
            {
                if(dis[i]>dis[j]||dis[i]>dis[k])
                {//当前点比儿子打,说明需要维护
                    if(dis[j]<dis[k])//将较小儿子与父亲交换
                    swap(heap[x],heap[x<<1]),
                    swap(pos[i],pos[j]),x<<=1;
                    else
                    swap(heap[x],heap[x<<1|1]),
                    swap(pos[i],pos[k]),x=x<<1|1;
                }
                else return;//当前点已经是最小的了
                //因此不需要维护,直接跳出
            }
            else if(dis[i]>dis[j])//若当前节点只有1个儿子
            swap(heap[x],heap[x<<1]),
            swap(pos[i],pos[j]),x<<=1;
        }
    }
    inline void siftup(int x)
    {//维护堆,将堆中第i号点往上移 
        while(x>1)
        {
            if(dis[heap[x]]<dis[heap[x>>1]])//若父亲比自己打
            swap(pos[heap[x]],pos[heap[x>>1]]),
            swap(heap[x],heap[x>>1]),x>>=1;
            //需要维护,交换
            else return;//不需要维护,跳出
        }
    }
    inline int pop()
    {//弹出堆顶元素并维护 
        int t=heap[1];
        pos[t]=0;
        heap[1]=heap[n];
        n--;
        pos[heap[1]]=1;
        siftdown(1);
        return t;
    }
    void dijkstra()
    {
        dis[p]=0;tot=n;
        swap(heap[p],heap[1]);
        swap(pos[heap[p]],pos[heap[1]]);
        //初始化 
        while(n)
        {
            int k=pop();//取堆顶元素 
            for(int i=frt[k];i;i=nxt[i])
            if(dis[v[i]]>dis[k]+w[i])
            dis[v[i]]=dis[k]+w[i],
            siftup(pos[v[i]]);
            //进行松弛操作并维护堆 
        }
    }
    int main()
    {
        memset(dis,inf,sizeof(dis));
        //初始化 
        n=read();m=read();p=read();
        for(int i=1;i<=n;i++)
        heap[i]=i,pos[i]=i;//初始化 
        while(m--)
        {
            int x=read(),y=read(),z=read();
            add(x,y,z);//建图 
        }
        dijkstra();//调用最短路算法 
        for(int i=1;i<=tot;i++)
        write(dis[i]),putchar(' ');
        //愉快输出答案 
    }

    不要太依赖于STL!!!很多时候STL无法灵活使用,学会手动实现很重要!!!

    感觉自己好蒟啊,写手打堆得原因是根本就用不来STL优先队列

  • 相关阅读:
    git版本库管理介绍,撤销git pull操作
    【laravel5.4】自定义404、503等页面
    【laravel5.4】{{$name}}、{{name}}、@{{$name}} 和 @{{name}} 的区别
    python 了解一点属性的延迟计算
    python 了解一下__dict__
    excel怎么把一个sheet的 全部内容打印到一页纸上
    python 简单了解一下 描述器
    python 调用父类方法, 重写父类构造方法, 不显式调用,会报错
    Python 今天抽空学习了@Property
    python 语法糖是什么意思
  • 原文地址:https://www.cnblogs.com/jvruo/p/10337445.html
Copyright © 2011-2022 走看看