最短路 dijstra算法
先了解原理:https://www.cnblogs.com/jason2003/p/7222182.html
看题:
Problem Description
给定一个带权无向图,求节点1到节点n的最短路径。
Input
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。
Output
每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)
Sample Input
3 2
1 2 1
1 3 1
1 0
Sample Output
1
0
代码:
#include <iostream>
#include <cstring>
#define INF 0x3f3f3f
using namespace std;
int n,m;
int a[102][102];
int via[102];
int dis[102];
int i,j;
void dijstra( int v0 )
{
for ( i=1; i<=n; i++ ) { // dis数组的初始化
dis[i] = a[v0][i];
}
while ( 1 ) {
int minn = INF;
int u;
for ( i=1; i<=n; i++ ) { // 寻找未标记节点的最小值
if ( dis[i]<minn && via[i]==0 ) {
minn = dis[i]; // 存权值
u = i; // 存节点
}
}
if ( minn==INF ) { // 没找到最小值,跳出循环
break ;
}
via[u] = 1; // 容易遗漏,标记找到的最小值点
for ( i=1; i<=n; i++ ) { // 更新最短路
if ( via[i]==0 && a[u][i]<INF && dis[i]>dis[u]+a[u][i] ) {
dis[i] = dis[u]+a[u][i];
}
}
}
if ( m==0 ) {
cout << "-1" << endl; // 不存在最短路
}
else {
cout << dis[n] << endl;
}
}
int main()
{
while ( cin>>n>>m ) {
memset(a,INF,sizeof(a)); // 将两点之间的权值设成最大,即不连通
memset(via,0,sizeof(via));
for ( i=1; i<=n; i++ ) { // 将自己与自己的权值设置为0
a[i][i] = 0;
}
for ( i=0; i<m; i++ ) {
int x,y,z;
cin >> x >> y >> z;
if ( a[x][y]>z ) { // 这个判断必须加,防止两点之间,有多条权值不同的边
a[x][y] = a[y][x] = z; // 连通就更新a,无向图
}
}
dijstra(1);
}
return 0;
}