zoukankan      html  css  js  c++  java
  • 最短路

    迪杰斯特拉

    算法重点是松弛操作,解释为用一个dis数组记录从起点走到当前点的最短距离,如果当前点的dis值加上走到相邻点的距离小于相邻点的dis值,则更新相邻点的dis为前面两数之和。之后不断维护dis的值直到终点。

    实现方面可以用优先队列不断取出dis值小的点,到终点结束。

    head提前全置为-1,无向图需要st和ts的顺序插入两遍

    nnum:顶点数 egnum:边数

    点标号从0开始

    优先队列

    const int INF = 0xfffffff;
    struct Edge{
        int s, t, v, nxt;
    }e[1000005];
    int n, m, cnt, head[100005], dis[100005], vis[100005];
    void add(int s, int t, int v){
        e[cnt].s = s; e[cnt].t = t; e[cnt].v = v; e[cnt].nxt = head[s]; head[s] = cnt++;
    }
    struct Heap{
        int s, d;
        friend bool operator <(Heap a, Heap b){
            return a.d > b.d;
        }
    };
    void INIT(){
        cnt = 0;
        memset(head, -1, sizeof(head)); 
    } 
    void Dijkstra(int s, int N){
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= N; i++) 
            dis[i] = INF;
        dis[s] = 0;
        priority_queue <Heap> q;
        Heap start;
        start.s = s; start.d = dis[s];
        q.push(start);
        while(!q.empty()){
            Heap u = q.top();
            q.pop();
            if(vis[u.s]) continue;
            vis[u.s] = 1;
            for(int i = head[u.s]; i != -1; i = e[i].nxt){
                int t = e[i].t;
                if(!vis[t] && dis[t] > e[i].v + dis[u.s]){
                    dis[t] = e[i].v + dis[u.s];
                    Heap e;
                    e.s = t; e.d = dis[t];
                    q.push(e);
                }
            }
        } 
    }
    View Code

    手写堆

    const int INF=0xfffffff ;
    const int egnum=200005 ;
    const int nnum=1005 ;
    struct node
    {
        int s,t,v ;
        int nxt ;
    } ;
    node e[egnum] ;
    int cnt,head[nnum] ;
    void add(int s,int t,int v)
    {
        e[cnt].s=s ;e[cnt].t=t ;e[cnt].v=v ;e[cnt].nxt=head[s] ;head[s]=cnt++ ;
    }
    int dis[nnum],vis[nnum] ;
    struct heap
    {
        int s,d ;
    } ;
    heap hp[nnum] ;
    int heapsize ;
    void up(int son)
    {
        while(son!=1)
        {
            if(hp[son>>1].d>hp[son].d)
            {
                swap(hp[son>>1],hp[son]) ;
                son>>=1 ;
            }
            else
                break ;
        }
    }
    void down(int fa)
    {
        int son=fa<<1 ;
        while(son<=heapsize)
        {
            if(son<heapsize && hp[son+1].d<hp[son].d)
                son++ ;
            if(hp[fa].d>hp[son].d)
            {
                swap(hp[fa],hp[son]) ;
                fa=son ;son<<=1 ;
            }
            else break ;
        }
    }
    void pop()
    {
        swap(hp[1],hp[heapsize--]) ;
        down(1) ;
    }
    void push(heap x)
    {
        hp[++heapsize]=x ;
        up(heapsize) ;
    }
    void Dijkstra(int s,int n)
    {
        heapsize=0 ;
        memset(vis,0,sizeof(vis)) ;
        for(int i=1 ;i<=n ;i++)
        {
            if(i==s)
                dis[i]=0 ;
            else    
                dis[i]=INF ;
        }
        heap st ;
        st.s=s ;st.d=dis[s] ;
        push(st) ;
        while(heapsize)
        {
            heap u=hp[1] ;
            pop() ;
            if(vis[u.s])continue ;
            vis[u.s]=1 ;
            for(int i=head[u.s] ;i!=-1 ;i=e[i].nxt)
            {
                int tt=e[i].t ;
                if(!vis[tt] && dis[tt]>e[i].v+dis[u.s])
                {
                    dis[tt]=e[i].v+dis[u.s] ;
                    heap ttt ;
                    ttt.s=tt ;ttt.d=dis[tt] ;
                    push(ttt) ;
                }
            }
        } 
    }
    View Code
  • 相关阅读:
    Effective C++学习笔记:确定基类有虚析构函数
    WPF和Silverlight程序中DispatcherTimer与Timer的区别
    2011.12.23
    WP7里的JSON解析
    2011.11.16
    2011.12.21
    2011.11.18
    2011.11.17
    2011.11.24
    WebClient does not support concurrent I/O operations 错误的解决办法
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3457120.html
Copyright © 2011-2022 走看看