hiho dijstra

#include 
#include
using namespace std;
const int maxnum = 1005;
const int inf = 0x3f3f3f3f;
// 各数组都从下标1开始
int dist[maxnum];     // 表示当前点到源点的最短路径长度
int path[maxnum];     // 记录当前点的前一个结点
int c[maxnum][maxnum];   // 记录图的两点间路径长度
int N, M, S, T;             // 图的结点数和路径数
void Dijkstra(int n, int v, int dist[], int path[], int c[maxnum][maxnum])
{
	bool s[maxnum];    // 判断是否已存入该点到S集合中
	for (int i = 1; i <= n; ++i)
	{
		dist[i] = c[v][i];
		s[i] = 0;     // 初始都未用过该点
		if (dist[i] == inf)
			path[i] = 0;//表明此时不存在v到i的路径
		else
			path[i] = v;
	}
	dist[v] = 0;
	s[v] = 1;
	// 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
	// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
	for (int i = 2; i <= n; i++)
	{
		int tmp = inf;
		int u = v;
		// 找出当前未使用的点j的dist[j]最小值
		for (int j = 1; j <= n; ++j)
		{
			if (!s[j] && dist[j] < tmp)
			{
				u = j;              // u保存当前邻接点中距离最小的点的号码
				tmp = dist[j];
			}
		}
		s[u] = 1;    // 表示u点已存入S集合中
		// 更新dist
		for (int j = 1; j <= n; ++j)
		{
			if (!s[j] && c[u][j] < inf)
			{
				int newdist = dist[u] + c[u][j];
				if (newdist < dist[j])
				{
					dist[j] = newdist;//如果这个采用了的话,之后的最短路径,其父亲必是u
					path[j] = u;
				}
			}
		}
	}
}
int main()
{
	// 各数组都从下标1开始
	// 输入结点数 输入路径数
	cin >> N >> M >> S >> T;
	int u_i, v_i, length_i;          // 输入p, q两点及其路径长度
	// 初始化c[][]为inf
	memset(c, inf, sizeof(c));
	for (int i = 1; i <= M; ++i)
	{
		cin >> u_i >> v_i >> length_i;
		if (c[u_i][v_i] == 0)
		{
			c[u_i][v_i]=c[v_i][u_i] = length_i;
		}
		else if (length_i < c[u_i][v_i])       // 有重边
		{
			c[u_i][v_i]=c[v_i][u_i] = length_i;      // p指向q
		}
	}
	for (int i = 1; i <= N; ++i)
		dist[i] = inf;
	Dijkstra(N, S, dist, path, c);
	cout << dist[T] << endl;
	return 0;
}

你可能感兴趣的:(图论)