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\t",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\n",road[k]);
        }
    }
    return 0;
}
           
蓝桥:
 http://lx.lanqiao.org/problem.page?gpid=T15
posted @ 2013-07-30 11:58  哥的笑百度不到  阅读(301)  评论(0编辑  收藏  举报