最短路

迪杰斯特拉

算法重点是松弛操作,解释为用一个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

 

你可能感兴趣的:(最短路)