最短路(Dijstra算法)

题目网址:最短路

这个问题之前使用的是floyd算法,这里介绍另外一种Dijstra算法。

Dijstra算法流程:

(1)初始化,集合k加入节点1,节点1到自己的最短路径为0,到其他节点为INF;

(2)遍历与集合k节点直接相连的边(u,v,c),其中u属于集合k,v不属于k,计算由结点1出发按照已经得到的最短路到达u,再由u经过该边到达v时的路径长度。比较所有与集合k中结点直接相连的非集合k的节点的路径长度,其中路径长度最小的节点就确定了下一个最短路径确定的结点,其最短路径即为这个路径长度,最后将这个结点加入集合k;

(3)如果集合k已经包含了所有的节点,结束,否则转(2)。

#include
#include
#include
using namespace std;
struct e{//邻接链表中链表元素结构体
	int next;//代表直接相连的节点
	int cost;//代表该边的权值(长度)
};
const int INF = 123123123;
vector edge[101];//邻接链表
bool mark[101];//标记,当mark[i]为true表示节点i的最短路径长度已经得到,该节点已经加入集合k中
int dist[101];//距离,当mark[i]为true的时候,dist[i]表示已经得到的最短路径的长度,否则表示所有从结点1出发,经过已经知道的最短路径达到集合k的某个节点,
//在经过一条边到达节点i的路径的最短长度
int main()
{
	int n, m;
	while (cin >> n >> m&&n&&m)
	{
		for (int i = 1; i <= n; i++)
		{//初始化
			edge[i].clear();
			mark[i] = false;
			dist[i] = INF;//如果这里dist[i]初始化为-1,注意下面更新之处两个变化
		}
		while (m--)
		{
			int a, b, c;
			cin >> a >> b >> c;
			e tmp;
			tmp.next = b;
			tmp.cost = c;
			edge[a].push_back(tmp);
			tmp.next = a;//因为是无向图,所以
			edge[b].push_back(tmp);
		}
		dist[1] = 0;
		mark[1] = true;
		int newp = 1;
		for (int i = 1; i < n; i++)
		{
			for (int j = 0; j < edge[newp].size(); j++)
			{
				int t = edge[newp][j].next;
				int c = edge[newp][j].cost;
				if (mark[t])
					continue;//如果这个节点已经属于k,那么不考虑了
				if (dist[t]>dist[newp] + c)//if(dist[t]==-1||dist[t]>dist[newp]+c)
				{//如果这个节点尚不可达,或者新加入的节点经过一条边到达时比以往的距离更短
					dist[t] = dist[newp] + c;//更新其距离信息
				}
			}
			int min = 123123123;
			for (int j = 1; j <= n; j++)
			{//遍历所有的节点,找到不在k中,且距离最小的那个节点加入k集合,更新他的mark为true
				if (mark[j])
					continue;
				/*
				if(dist[j]==-1)
				   continue;
				*/
				if (dist[j] < min)
				{
					min = dist[j];
					newp = j;
				}
			}
			mark[newp] = true;
		}
		cout << dist[n] << endl;
	}
	return 0;
}
/**************************************************************
Problem: 1447
User: hellosyqq
Language: C++
Result: Accepted
Time:30 ms
Memory:1520 kb
****************************************************************/



你可能感兴趣的:(最短路径)