最短路SPFA

#include <iostream>
#include <queue>
using namespace std ;

const int M = 1000 + 10 ;
const int INF = 0x3ffffff;

int dis[M];      //dis[i],点i到源点的最短路径
int map[M][M];            
int used[M];     //used[i],标记点i是否在队列中

int SPFA(int start , int end ,int n)        //起点,终点,总点数编号为[1,n]
{

    dis[start] = 0;     //初始化dis[源点]为0,并且源点进队列
    
    queue<int>Q;
    Q.push(start);
    used[start] =1 ;
    
    while(!Q.empty())
    {
        int head = Q.front();
        Q.pop();
        used[head] = 0;               //出队列就解除标记
        
        for(int i=1; i<=n; i++)
        {
            if(map[head][i] != INF && dis[head] + map[head][i] < dis[i])    //松弛操作
            {
                dis[i] = dis[head] + map[head][i];
                
                if(!used[i])    //i被更新,且不在队列中
                {
                    used[i] = 1;  //进队就标记
                    Q.push(i);
                }
            }
        }
    }
    return dis[end] ;        //不能在松弛时找到end就结束,因为有负边可能会找到更短的路径
}


void init()
{
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<M;j++)
        {
            map[i][j]=INF;                    //初始化图没有边,全部距离为无穷大INF
        }
        dis[i]=INF;    
    }
    memset(used,0,sizeof(used));
}


int main()
{
    int n,m;
    int a,b,c;
    while(cin>>n>>m,n+m)
    {
        init() ;
        while(m--)
        {
            cin>>a>>b>>c;
            if(c<map[a][b])                        //判重边
            {
                   // map[a][b]=map[b][a]=c;            //无向边
                     map[a][b]=c;                    //SPFA只适用于有向边
            }
        }
        
        
        cout<< SPFA(1,n,n)  <<endl;
        
    }
    return 0;
}




/*

  
Sample Input:
    
5 5
1 2 2
2 3 5
2 4 6
4 3 -2
3 5 4
      
Sample Output :
10
          
            
*/

 

posted on 2012-09-03 19:06  [S*I]SImMon_WCG______*  阅读(180)  评论(0编辑  收藏  举报

导航