/**
* 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;
}
* 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;
}