// 单源最短路径问题的整理
// 需要的数据结构:map[i][j]用来存放点与点之间的权used[i]用来标记点是否已经被用过dist[i]用来动态记录从 起点到该点的最短距离
// 具体的操作步骤
// 1. 初始化各项内容
// 2. 在使用的点中找出已经求出的确定的最短路径,并标记为已使用
// 3. 根据已经确定的最短路径的点,更新其余的dist[i]
#include<iostream>
#include<vector>
#define MAX_V 6000 //最多5000个顶点
#define INF 5000 // 最长是5000
using namespace std;
int V;
int N;
int R;
int map[MAX_V][MAX_V];
int dist[MAX_V];
int dist2[MAX_V];
bool used[MAX_V];
// solve的功能,找到以s为起点的到各个点的最短路径和次短路径
void solve(int s){ // s是源点
fill(dist, dist + V, INF);
fill(dist2, dist2 + V, INF);
fill(used, used + V, false);
dist[s] = 0;
while(true){
// 先找dist中的最小值,把这个值对应的点作为一个最近的点,同时标记为used
int v = -1;
int i;
int a, b;
for(i = 0; i < V; i++){
if(!used[i] && (v == -1 || dist[i] < dist[v]))
v = i;
}
if(v == -1)
break;
used[v] = true;
for(i = 0; i < V; i++){
dist[i] = min(dist[i], dist[v]+map[v][i]);
int m = INF;
for(int j = 0; j < V; j++){
a = dist[j]+map[i][j];
b = dist2[j] + map[i][j];
if(a == dist[i])
m = min(m, b);
else{
m = min(m,a);
m = min(m,b);
}
}
dist2[i] = m;
}
}
cout <<dist2[V-1] << endl;
}
int main(){
cin >> N >> R;
V = N;
int x, y, d;
for(int i = 0; i < V; i++){
for(int j = 0; j < V; j++){
map[i][j] = INF;
}
}
for(int i = 0; i < R; i++){
cin >> x >> y >> d;
map[x-1][y-1] = d;
map[y-1][x-1] = d;
}
solve(0);
// system("pause");
return 0;
}
// 由于内存占用太大,poj上没有通过
单源次短路径
最新推荐文章于 2025-06-27 17:32:41 发布