• SPFA_vertor


    #include<iostream>
    #include<vector>
    #include<queue>
    using namespace std;
    const int N = 100;
    const int INF = 0x3f3f3f3f;
    struct Edge{   //用于记录一组关系
        int u,v,w;
    };
    
    vector<Edge> edge[N];  //用于保存图的关系
    int flag[N];      //用于标记是否在队列中
    int dis[N];      //源点到各点的最短距离
    int path[N];     //源点到各点的路径
    int road[N];     //用于逆向追中输出路径
    
    void init(int n){
        for(int i=0;i<n;i++){
            if(!edge[i].empty()){
                edge[i].clear();
            }
        }
    }
    
    void SPFA_vector(int v,int n){   //源点,顶点数
        int i;
        memset(path,255,sizeof(path));   //初始化路径为-1;
        memset(flag,false,sizeof(flag));     //初始化为false,表示不在队列
        for(i=0;i<=n;i++){               //初始化dis[i]为不可到达
            dis[i] = INF;
        }
        dis[v] = 0;      //把源点到自己的路径改为0
        queue<int> q;    //定义一队列来维护
        q.push(v);       //把源点放进队列开始扩展 
        while(!q.empty()){
            int temp = q.front(); //取队列的第一个点进行扩展
            q.pop();               //出列
            flag[temp]=false;      //出列后标记为false
            for(i=0;i<edge[temp].size();i++){ //枚举所有与该点出发的边
                int w = edge[temp][i].w;      //改点到下一点的权值
                int v = edge[temp][i].v;      //改点到下一点的顶点
                if(dis[temp] + w < dis[v]){   //如果可以扩展
                    dis[v] = dis[temp] + w;   //更新
                    path[v] = temp;           //标记路径
                    if(!flag[v]){             //如果不在队列中
                        q.push(v);            //添加进队列维护
                        flag[v] = true;       //标记为在队列
                    }
                }
            }
        }
    }
    
    int main(){
        freopen("in.txt","r",stdin);
        int n;
        Edge temp;
        while(scanf("%d",&n)!=EOF){
            init(n);
            while(scanf("%d%d%d",&temp.u,&temp.v,&temp.w) && ~temp.u && ~temp.v && ~temp.w){
                edge[temp.u].push_back(temp);  //把关系添加到vector
            }
            SPFA_vector(0,n);
    
            for(int i=1;i<n;i++){
                printf("%d	",dis[i]);  //输出最短路
    
                int k=0;               //用于标记要经过几个点
                road[k] = i;           //保存第一个点
                while(path[road[k]] != -1){//若还有前继点,逆向追踪
                    k++;
                    road[k] = path[road[k-1]];
                }
                while(k){              //输出路径
                    printf("%d->",road[k--]);
                }
                printf("%d
    ",road[k]);
            }
        }
        return 0;
    }
               
    蓝桥:
     http://lx.lanqiao.org/problem.page?gpid=T15
  • 相关阅读:
    练习 字符串存入字典 数组的降序 倒序 字符串目录存不存在 数组中文排序
    随机 随机获得100个50-100的数字字符串,存到数组并输出
    练习 字符串10题
    把一个字符串反输出abc123.xyz789输出987zyx.321cba
    把NSString *string=@"2013 年 05 月 05 日";以2013-05-05输出
    dephi cef3获取Post数据
    Delphi下 多显示器,将窗体显示于第二个显示器
    Delphi下POS机
    SQLConnection 连接 SQLite
    cxGrid主视图取得从视图
  • 原文地址:https://www.cnblogs.com/Deng1185246160/p/3224844.html
Copyright © 2020-2023  润新知