源点到所有顶点的最短路径
程序员文章站
2024-03-15 18:58:24
...
//源点到其余各点的最短路径
//从源点出发 遍历邻接点 每次选择最小的路径 作为次长
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define MAXSIZE 256
struct BaseNode
{
BaseNode(){
tailIndex = -1;
nWeight = -1;
Next = NULL;
}
int tailIndex;
int nWeight;
BaseNode * Next;
};
struct GraphNode
{
GraphNode(){
info = '\0';
first = NULL;
}
char info;
BaseNode * first;
};
class Graph
{
public:
Graph()
{
m_VertSize = -1;
m_EdgeSize = -1;
}
public:
bool Init();
void FindMin(int nStart);
public:
GraphNode m_Node[MAXSIZE];
int m_VertSize;
int m_EdgeSize;
};
bool Graph::Init()
{
cout << "输入节点数" << endl;
cin >> m_VertSize;
for (int i = 1; i <= m_VertSize; i++)
{
char info;
cin >> info;
m_Node[i].info = info;
}
cout << "输入边数" << endl;
cin >> m_EdgeSize;
for (int i = 1; i <= m_EdgeSize; i++)
{
int nHead, nTail, nWeight;
cin >> nHead >> nTail >> nWeight;
if (m_Node[nHead].first == NULL)
{
m_Node[nHead].first = new BaseNode;
m_Node[nHead].first->tailIndex = nTail;
m_Node[nHead].first->nWeight = nWeight;
}
else{
BaseNode* t = m_Node[nHead].first;
while (t && t->Next )
{
t = t->Next;
}
t->Next = new BaseNode;
t->Next->tailIndex = nTail;
t->Next->nWeight = nWeight;
}
}
return true;
}
struct MinPath
{
MinPath()
{
index = -1;
path = "";
nLength = -1;
}
int index;
int nLength;
string path;
bool operator==(int a)
{
return a == index;
}
};
void Graph::FindMin(int nStart)
{
//nStart 到其他各点 情况初始化
vector<MinPath> allPath;
for (int i = 1; i <= m_VertSize; i++)
{
if (i != nStart)
{
MinPath p;
p.index = i;
allPath.push_back(p);
}
}
//从源点开始
vector<int> selectPoint,hasSelected;
selectPoint.push_back(nStart);
while (selectPoint.size() > 0)
{
int p = selectPoint[0];
//标记该点已选
hasSelected.push_back(p);
selectPoint.erase(selectPoint.begin());
//第一个邻接点
BaseNode * t = m_Node[p].first;
//记录 该点 当前 路径 和长度
string info="";
int nLength = 0;
vector<MinPath>::iterator name = find(allPath.begin(), allPath.end(), p);
if (name == allPath.end() || (*name).path == "")
{
info = m_Node[p].info;
nLength = 0;
}
else{
info = (*name).path;
nLength = (*name).nLength;
}
//遍历邻接点 替换最小 路径
while (t)
{
vector<MinPath>::iterator it = find(allPath.begin(), allPath.end(), t->tailIndex);
if (it != allPath.end())
{
if ((*it).nLength == -1 || ( (*it).nLength > t->nWeight + nLength ))
{
(*it).nLength = t->nWeight + nLength;
(*it).path = info;
(*it).path += m_Node[t->tailIndex].info;
}
}
t = t->Next;
}
int m = -1, n = -1;
//从未选过的点中 选择路径最短的点
for (int i = 0; i < allPath.size(); i++)
{
if (find(hasSelected.begin(), hasSelected.end(), allPath[i].index) == hasSelected.end())
{
if (allPath[i].nLength != -1 && ((m == -1 || m > allPath[i].nLength) ))
{
m = allPath[i].nLength;
n = allPath[i].index;
}
}
}
if (n != -1)
selectPoint.push_back(n);
}
for (int i = 0; i < allPath.size(); i++)
{
cout << allPath[i].path << allPath[i].nLength << endl;
}
}
int main()
{
Graph g;
if (g.Init())
{
g.FindMin(1);
}
return 0;
}