码迷,mamicode.com
首页 > 其他好文 > 详细

最短路径

时间:2018-07-08 23:05:08      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:math   size   clu   最短路径   最短路   条件   数组   mat   rom   

PS:求最长路只需把权值变为相反数

PS*2:有些题目对路径有额外要求,只需应用动态规划的思想在dis数组上加维以表示条件


SPFA

前向星
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

const long long INF=pow(2,50)-1;
long long n,m,sta,end;

long long front[100005],size[100005];

struct star{
    long long from,to,val;
}edge[100005];

long long co[100005];//用于记录路径 
long long dis[100005];
long long book[100005];//用于判负环 
long long que[500005];
long long head,tail;

long long out[100005];
long long outn=0;

long long cmp(star x,star y){
    if(x.from<y.from){
        return 1;
    }else if(x.from==y.from){
        if(x.to<y.to){
            return 1;
        }
        return 0;
    }
    return 0;
}

//特殊加边,本程序未使用
void addedge(long long x,long long y,long long z) {
    m++;
    edge[m].from=x;
    edge[m].to=y;
    edge[m].val=z;
    
}

long long init(){
    
    sort(edge+1,edge+m+1,cmp);

    long long jl=-1;
    for(long long i=1;i<=m;i++){
        if(edge[i].from!=jl){
            jl=edge[i].from;
            front[jl]=i;
        }
        size[jl]++;
    }
}

bool spfa(long long root){
    for(long long i=0;i<=n;i++){
        dis[i]=INF;
        co[i]=0;
        book[i]=0;
    }
    head=0;
    tail=0;

    que[tail]=root;
    tail++;
    dis[root]=0;

    for(;tail>head;){
        long long now=que[head];
        for(long long i=front[now];i<front[now]+size[now];i++){
            if(dis[edge[i].to]>dis[now]+edge[i].val){
                dis[edge[i].to]=dis[now]+edge[i].val;
                co[edge[i].to]=now;//记录路径 
                que[tail]=edge[i].to;
                tail++;
                book[edge[i].to]++;//该点入队次数+1 
                if(book[edge[i].to]>n){
                    return 0;//有负环 
                }
            }
        }
        head++;
    }
    return 1;//正常返回 
}

void outpath(){
    outn=0;
    long long ac=end;
    for(;;){
        out[outn]=ac;
        outn++;
        if(ac==sta){
            break;
        }
        ac=co[ac];
    }
    for(int i=outn-1;i>=0;i--){
        printf("%d ",out[i]);
    }
}

int main(){
    //输入 
    cin>>n>>m>>sta>>end;
    for(long long i=1;i<=m;i++){
        long long t1,t2,t3;
        scanf("%lld%lld%lld",&t1,&t2,&t3);
        edge[i].from=t1;
        edge[i].to=t2;
        edge[i].val=t3;
    }
    init();
    //计算&判负环 
    if(spfa(sta)==0){
        cout<<"No"; 
        return 0;//退出程序 
    }
    //输出长度 
    cout<<dis[end]<<endl;
    //输出路径 
    outpath();
    return 0;
}
/*输出边
for(int i=1;i<=n;i++){
        cout<<"===="<<i<<endl;
        for(int j=front[i];j<front[i]+size[i];j++){
            cout<<edge[j].from<<‘ ‘<<edge[j].to<<‘ ‘<<edge[j].val<<endl;
        }
    }
*/

最短路径

标签:math   size   clu   最短路径   最短路   条件   数组   mat   rom   

原文地址:https://www.cnblogs.com/sun123zxy/p/shortestpath.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!