题目描述
在带权有向图G中,给定一个源点v,求从v到G中的其余各顶点的最短路径问题,叫做单源点的最短路径问题。
在常用的单源点最短路径算法中,迪杰斯特拉算法是最为常用的一种,是一种按照路径长度递增的次序产生最短路径的算法。
在本题中,读入一个有向图的带权邻接矩阵(即数组表示),建立有向图并按照以上描述中的算法求出源点至每一个其它顶点的最短路径长度。
输入
输入的第一行包含2个正整数n和s,表示图中共有n个顶点,且源点为s。其中n不超过50,s小于n。
以后的n行中每行有n个用空格隔开的整数。对于第i行的第j个整数,如果大于0,则表示第i个顶点有指向第j个顶点的有向边,且权值为对应的整数值;如果这个整数为0,则表示没有i指向j的有向边。当i和j相等的时候,保证对应的整数为0。
输出
只有一行,共有n-1个整数,表示源点至其它每一个顶点的最短路径长度。如果不存在从源点至相应顶点的路径,输出-1。
请注意行尾输出换行。
样例输入
4 1 0 3 0 1 0 0 4 0 2 0 0 0 0 0 1 0
样例输出
6 4 7
Dijkstra算法:
AC:
#include<iostream>
using namespace std;
#define INF 999999
int e[55][55]; //邻接矩阵
int dis[55]; //源点至各个结点的最短路径
int p[55] = {0}; //标志
int s,n;
int main()
{
cin >> n >> s; //顶点个数与源点
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> e[i][j];
if (e[i][j] == 0&&i!=j)e[i][j] = INF; //输入邻接矩阵,对角线为0,不可达为INF
if (i == s)dis[j] = e[i][j]; //初始化dis
}
}
for (int i = 0; i < n - 1; i++) //n-1次即可遍历完
{
int min = INF;
int u;
for (int j = 0; j < n; j++) //寻找距离源点最近的点
{
if (j != s&&p[j] == 0 && dis[j] < min)
{
min = dis[j];
u = j;
}
}
p[u] = 1; //选中,记录
for (int v = 0; v < n; v++) //对u的所有出边进行松弛(即以u为中间节点)
{
if (e[u][v] < INF)
{
if (dis[v] > dis[u] + e[u][v]) //u为中间结点
{
dis[v] = dis[u] + e[u][v];
}
}
}
}
for (int i = 0; i < n; i++)
{
if (i != s)
{
if (dis[i] == INF)cout << -1<<" ";
else cout << dis[i] << " ";
}
}
cout << endl;
return 0;
}