0
点赞
收藏
分享

微信扫一扫

北林OJ_273

#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;
}

北林OJ_273_最短路径

举报

相关推荐

0 条评论