//仅供学习参考之用,无对应题目,求源点至各点的最短路
// 初始:dis[k] = Map[v0][k] ,v0为源点
// 递推:u=min{dis[t]},vt属于T
// dis[k]=min{dis[k],dis[u]+Map[u][k]},Vk属于T
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
int Map[20][20]; //邻接矩阵
bool vis[20]; //标记是否处理过
int dis[20]; //当前找到从源点至终点Vi的最短长度
void Dijkstra(int v0)
{
int u,qmin;
for(int i=0; i<n; i++)
{
dis[i] = Map[v0][i];
if(i!=v0 && dis[i]<INF)
pas[i] = v0;
else
pas[i] = -1;
}
vis[v0] = 1;
dis[v0] = 0;
for(int i=0; i<n-1; i++)
{
qmin = INF,u = v0;
for(int j=0; j<n; j++) //选择当前集合中具有最短路的顶点u
{
if(!vis[j] && dis[j] < qmin)
{
u = j;
qmin = dis[j];
}
}
vis[u] = 1; //将顶点u标记,表示最短路已经求到
for(int k=0; k<n; k++) //修改当前集合中顶点的dis和pas数组元素值
{
if(!vis[k] && Map[u][k] < INF && dis[u]+Map[u][k] < dis[k])
{
dis[k] = dis[u]+Map[u][k];
}
}
}
}
int main()
{
int u,v,w;//边的起点,终点以及权值
while(cin>>n>>m)
{
memset(Map,0,sizeof(Map));
memset(vis,0,sizeof(vis));
for(int i=0; i<m; i++)
{
cin>>u>>v>>w;
Map[u][v] = w;
}
for(int i = 0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(i == j)
Map[i][j] = 0;
else if(Map[i][j] == 0)
Map[i][j] = INF;
}
}
Dijkstra(0);
for(int i=1; i<n; i++)
{
cout<<"0->"<<i<<": "<<dis[i]<<endl;
}
}
return 0;
}
越獄之权值非负单源最短路径问题-Dijkstra算法
最新推荐文章于 2022-01-22 16:04:57 发布