最短路径单向

/**
 * DIJKSTRA(简单版) 单源最短路径算法(不允许存在负边)
 * 输入:(1)图g;        // 有向图或者无向图
 *         (2)源点s。
 * 输出:(1)源点s到各点的最短路径长dist;
 *         (2)源点s到各点的最短路径prev。
 * 结构: 图g用邻接矩阵表示,最短路径长dist用数组表示。
 * 算法:Dijkstra算法  
 * 复杂度:O(|V|^2)
 */
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <functional>
#include <climits>
using namespace std;

//const int StartNode = 1;                    // StartNode : 源点(source)

map<int, vector<int> > LineMap;

int node_num = 0;                    // node_num : 顶点个数
int MAX_NODE = 0;
int MIN_NODE = INT_MAX;
int SourceNode;

vector<vector<int> > graph;     // graph : 图(graph)(用邻接矩阵(adjacent matrix)表示)
vector<bool> known;             // known : 各点是否知道最短路径
vector<int> dist;               // dist : 源点s到各点的最短路径长
vector<int> prev;               // prev : 各点最短路径的前一顶点

void Dijkstra()            // 贪心算法(Greedy Algorithm)
{
    int i;
    int min;
    int next_node;
    int StartNode = MIN_NODE;
    known.assign(MAX_NODE, false);
    dist.assign(MAX_NODE, INT_MAX);
    prev.resize(MAX_NODE);            // 初始化known、dist、prev。
    dist[StartNode] = 0;            // 初始化源点s到自身的路径长为0。
     
    for (;;)
    {
        min = INT_MAX;
        next_node = StartNode;
        for (i = StartNode; i < MAX_NODE; i++)
        {
            if (!known[i] && min > dist[i])
            {
                min = dist[i];
                next_node = i;    // 寻找未知的最短路径长的顶点v,
            }
        }
         
        if (min == INT_MAX)
        {
            //cout << "zeng" << endl;
            break;        // 如果找不到,退出;
        }
        
        known[next_node] = true;                // 如果找到,将顶点v设为已知,
         
        for (i = StartNode; i < MAX_NODE; i++)        // 遍历所有v指向的顶点w,
        {
            if (!known[i] && graph[next_node][i] < INT_MAX && dist[i] > dist[next_node] + graph[next_node][i])
            {
                dist[i] = dist[next_node] + graph[next_node][i];
                prev[i] = next_node;    // 调整顶点w的最短路径长dist和最短路径的前一顶点 prev。
                //prev[prev[i]]  = i;
                
                //cout << prev[i] << "-->" << i << endl;
                //cout << prev[prev[i]] << "-->" << prev[i] << endl;
            }
        }
        //cout << "luoling" << endl;        
    }
}

void Print_SP(int next_node)
{
     if (next_node != SourceNode)
     {
        //cout << "next_node = " << next_node << endl;
        Print_SP(prev[next_node]);
     }
     cout << next_node << " ";
}

void GetShortLine(int src_node, int dst_node)
{
    int i;
    SourceNode = src_node;
    for (i = MIN_NODE; i < MAX_NODE; ++i)
    {
        if(dist[i] != MAX_NODE)
        {
            if (i == dst_node)
            {
                cout << MIN_NODE << "->" << i << ": ";
                Print_SP(i);
                cout << endl;
            }
        }
    }
}

int GetShortLen(int src_node, int dst_node)
{
    return dist[dst_node];
}

void AddLine(int LineNo, int StationNum, int *StationArray)
{
    int i;
    int station;
    map<int, vector<int> >::iterator map_iter;
    vector<int>::iterator            vec_iter;
    vector<int> StationVec;
    
    if (NULL == StationArray)
    {
        return;
    }
    
    map_iter = LineMap.find(LineNo);
    if (map_iter == LineMap.end())
    {
        StationVec.clear();
        for (i = 0; i < StationNum; i++)
        {
            station = StationArray[i];
            StationVec.push_back(station);
            if (station > MAX_NODE)
            {
                MAX_NODE = station;
            }
            if (station < MIN_NODE)
            {
                MIN_NODE =  station;
            }
        }
        LineMap.insert(pair<int, vector<int> >(LineNo, StationVec));
    }
    
    return;
    
}

void InitGraph()
{
    int i;
    int FirstNode;
    int NextNode;
    map<int, vector<int> >::iterator MapIter;
    vector<int>::iterator            VecIter;    
    
    MAX_NODE = MAX_NODE + 1;

    graph.assign(MAX_NODE, vector<int>(MAX_NODE, INT_MAX));
    
    for (MapIter = LineMap.begin(); MapIter != LineMap.end(); MapIter++)
    {
        for (i = 0; i < MapIter->second.size() - 1; i++)
        {
            FirstNode = MapIter->second[i];
            NextNode  = MapIter->second[i+1];
            graph[FirstNode][NextNode] = 1;
            graph[NextNode][FirstNode] = 1;                 
        }   
    }
}

int main()
{
    int i;
    //int line[5] = {6, 9, 10, 3, 5};
    int line_1[5] = {3, 6, 9, 11, 15};
    int line_2[5] = {16, 24, 9, 18, 19};    
    int LineNo = 1;
    int NodeNum = 5;
    int retval;
    
    AddLine(1, 5, line_1);
    AddLine(2, 5, line_2);
    
    InitGraph();
    
    //cout << "MIN_NODE = " << MIN_NODE << endl;
    
    //StartNode = 0;
    Dijkstra();
    
    GetShortLine(6, 16);
    retval = GetShortLen(6, 16);
    cout << retval << endl;
    // copy(dist.begin(), dist.end(), ostream_iterator<int>(cout, " ")); cout << endl;
    

    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值