最短路模板

6 篇文章 0 订阅

bellman-ford

求单源最短路,可以判断有无负权回路(若有,则不存在最短路),时效性较好,时间复杂度O(VE)。

 

bool bellman(){
    int i, j;
    for(i=1; i<n; i++){
        for(j=0; j<num; j++){
            if(d[edge[j].s]+edge[j].v<d[edge[j].e])
                d[edge[j].e]=d[edge[j].s]+edge[j].v;
        }
    }
    for(j=0; j<num; j++){
        if(d[edge[j].s]+edge[j].v<d[edge[j].e])
        return false;
    }
    return true;
}

 

spfa

是Bellman-Ford的队列优化,时效性相对好,时间复杂度O(kE)。(k<<V)。

与Bellman-ford算法类似,SPFA算法采用一系列的松弛操作以得到从某一个节点出发到达图中其它所有节点的最短路径。所不同的是,SPFA算法通过维护一个队列,使得一个节点的当前最短路径被更新之后没有必要立刻去更新其他的节点,从而大大减少了重复的操作次数。

 

bool spfa(int g, int st){
    int i, head, s;
    for(i=1; i<=n; i++){
        inqueue[i]=0;
        d[i]=INF;
    }
    queue<int > q;
    d[st]=0;
    inqueue[st]=1;
    q.push(st);
    while(!q.empty()){
        head=q.front();
        q.pop();
        inqueue[head]=0;
        s=pre[g][head];
        while(s!=-1){
            if(d[edge[g][s].v]>d[head]+edge[g][s].w){
                d[edge[g][s].v]=d[head]+edge[g][s].w;
                if(!inqueue[edge[g][s].v]){
                     inqueue[edge[g][s].v]=1;
                     q.push(edge[g][s].v);
                }
            }
            s=edge[g][s].next;
        }
    }
    return true;
}


 

 

FLOYD

求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度O(V^3)。

 

 void floyd(){
    int i, j, k;
    for( k=0; i<n; k++)
        for( i=0; i<n; i++)
            for( j=0; j<n; j++){
                if( i==k || i==j || j==k ) continue;
                if( len[i][k]+ len[k][j]< len[i][j]){
                    len[i][j]= len[i][k]+ len[k][j];
                    next[i][j]= next[k][j];
                }
            }
 }
void road(){//floyd 路径记录
    next[i][j]=j;          //init();
    next[i][j]=k;          //save
    int i=s, j=e;
    printf("%d ", i);
    while( next[i][j]!=j){
        printf("%d ",next[i][j]);
        i= next[i][j];
    }
    printf("%d\n", j);
}


 

dijkstra

求单源、无负权的最短路。时效性较好,时间复杂度为O(V*V+E)。

 

void  dijkstra(int graph[][101], int n)
{
    
int cov[101];
memset(cov,0,sizeof(cov));
memset(k,0,sizeof(k)); 
    int flag, i, j,min,max=0;
    for(i=1;i<=n;i++)
        k[i] = graph[1][i];    
    for(i=2;i<=n;i++)
    {
        min=MAX;                
        flag = 0;                          
        for(j=2;j<=n;j++)                
        {
            if(k[j]<min && cov[j]== 0)
            {
                min = k[j];        
                flag = j;                
            }
        }
                
        cov[flag] = 1;              
        for(j = 2; j <= n; j++)              
        {
            if(cov[j]==0&&graph[flag][j]>=0&&min+graph[flag][j]<k[j]) 
            {
                k[j] = graph[flag][j]+min;
            }
        }
    }
  
}


 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值