#include<iostream>
#include<iomanip>
using namespace std;
#define OK 1
#define ERROR 0
#define MVNum 10
#define Maxsize 10
#include<stdlib.h>
#include<math.h>
#include <stack>
const size_t npos = 345;//npos为无穷大的数
//邻接矩阵
typedef char VerTexType;//顶点数据类型
typedef int ArcType;//边的权值
typedef struct
{
VerTexType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻接矩阵
int vexnum, arcnum;//图的当前点数、边数
}AMGraph;
//查找顶点所在位置
int LocateVex(AMGraph G, VerTexType num);
//初始化邻接矩阵
void CreatMatrix(AMGraph& G);
//创建无向网
int CreateUDN(AMGraph& G);
//打印邻接矩阵
void print1(AMGraph G);
//打印最短路径
void print2(AMGraph G, VerTexType vex, VerTexType v);
//Dijsktra辅助数组
bool S[MVNum];//顶点是否已被访问
int D[MVNum];
int Path[MVNum];//存放顶点下标
/*初始化:S->源点为true, 其他均为false
* D->如果有弧,D元素为弧的权值,否则为无穷大
* Path->如果v0与v有弧,则Path[v]=v0,否则为-1
*/
void Init_SD(const AMGraph& G, VerTexType vex);
//最短路径
void ShortPath_DIJ(const AMGraph& G, VerTexType vex);
int LocateVex(AMGraph G, VerTexType num)
{
for (int i = 1; i <= G.vexnum; i++)
{
if (G.vexs[i] == num)
return i;
}
return 0;
}
void CreatMatrix(AMGraph& G)
{
VerTexType v1, v2;
int weight = 0;//权值
for (int k = 1; k <= G.arcnum; k++)//边
{
cin >> v1 >> v2 >> weight;
int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
if (j == 0 && i == 0)
exit(-1);
G.arcs[i][j] = weight;
}
}
int CreateUDN(AMGraph& G)
{
//创建
cin >> G.vexnum >> G.arcnum;//输入顶点数、总边数
if (G.vexnum == 0 && G.arcnum == 0)
return 0;
for (int i = 1; i <= G.vexnum; i++)//从1开始
{
cin >> G.vexs[i];
}
for (int i = 0; i < MVNum; i++)
{
for (int j = 0; j < MVNum; j++)
{
G.arcs[i][j] = npos;
}
}
//构造邻接矩阵
CreatMatrix(G);
return OK;
}
void print1(AMGraph G)
{
cout << setw(2) << ' ';
for (int i = 1; i <= G.vexnum; i++)//顶点
{
cout << setw(3) << G.vexs[i];
/*if (i != G.vexnum)
cout << ' ';*/
}
cout << endl;
for (int i = 1; i <= G.vexnum; i++)
{
cout << setw(2) << G.vexs[i] << ' ';
for (int j = 1; j <= G.vexnum; j++)
{
cout << setw(2) << G.arcs[i][j];
if (j != G.vexnum)
cout << ' ';
}
cout << endl;
}
}
void Init_SD(const AMGraph& G, VerTexType vex)
{
int k = LocateVex(G, vex);
for (int i = 1; i <= G.vexnum; i++)
{
if (i == k)
{
S[k] = true;
D[k] = 0;//源点到源点的距离为0
}
S[i] = false;
D[i] = G.arcs[k][i];
if (D[i] < npos)
Path[i] = k;
else
Path[i] = -1;
}
}
//最短路径
void ShortPath_DIJ(const AMGraph& G, VerTexType vex)
{
//初始化
Init_SD(G, vex);
//主循环:将vex邻接的最小权值的顶点v加入到S
for (int i = 1; i <= G.vexnum; i++)
{
int min = npos;
int v = 0;//记录最短路径终点下标
//找D中的最小权值
for (int j = 1; j <= G.vexnum; j++)
{
if (!S[j] && D[j] < min)//顶点未被访问且权值最小
{
v = j;
min = D[j];
////将最短路径v在Path中对应Path[v]=v0;
//Path[j]=
}
}
//把v加入到S
S[v] = true;
/*Path[v] = i;*/
//更新最短路径
for (int w = 1; w <= G.vexnum; w++)
{
if (!S[w] && D[v] + G.arcs[v][w] < D[w])
{
//更新D[w]
D[w] = D[v] + G.arcs[v][w];
Path[w] = v;
}
}
}
}
//打印最短路径
void print2(AMGraph G, VerTexType vex, VerTexType v)//vex 是源点v是终点
{
stack<char> stk;
int i = LocateVex(G, vex);
int k = LocateVex(G, v);
stk.push(G.vexs[k]);
int j = k;
while (j != i && j <= G.vexnum && j > 0)
{
if (Path[j] == -1)
{
break;//前面无路,就没有路
}
stk.push(G.vexs[Path[j]]);
j = Path[j];
}
cout << D[k]<< endl;//路径长度
//出栈并打印数据
while (!stk.empty())
{
cout <<stk.top() ;
stk.pop();
if (!stk.empty())
cout << ' ';
}
cout << endl;
}
void test273()
{
while (1)
{
AMGraph G;
int flag = CreateUDN(G);
if (!flag)
return;
VerTexType vex, v;//源点和终点
cin >> vex >> v;
ShortPath_DIJ(G, vex);
print2(G, vex, v);
}
}
int main()
{
test273();
return 0;
}
