把终点当成起点求到达每一个点的最短路径。用两次Dijkstra求分别求来回的最短路径,第一次求完之后保存到tem数组,然后把去来的路径反过来再次求最短路径,最后求加和之后的最大值就是答案;
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<stack>
#include<algorithm>
#include<queue>
#include<map>
#include<climits>
#define ll long long
using namespace std;
const int inf = 999999;
const int vex = 1005;
int v[vex][vex];
int dist[vex];
int vis[vex];
int tem[vex];
int n,m,x;
void dijkstra(int s){
fill(dist + 1, dist + 1 + n, inf);
fill(vis + 1, vis + 1 + n, 0);
dist[s] = 0;
for(int i = 1; i <= n; i++){
int now = s;
int temp = inf;
for(int j = 1; j <= n; j++){
if(!vis[j] && temp > dist[j]){
temp = dist[j];
now = j;
}
}
vis[now] = 1;
for(int j = 1; j <= n; j++){
if(!vis[j] && dist[j] > dist[now] + v[now][j]){
dist[j] = dist[now] + v[now][j];
}
}
}
if(tem[1] == -1){
for(int i = 1; i <= n; i++){
tem[i] = dist[i];
}
}
}
int main(){
scanf("%d %d %d",&n,&m,&x);
// for(int i = 1; i <= m; i++)
// fill(v[i] + 1, v[i] + 1 + m, inf);
for(int i = 1; i <= 1002; i++){
for(int j = 1; j <= 1002; j++){
v[i][j] = inf;
}
}
fill(tem + 1, tem + 1 + n, -1);
int a,b,c;
for(int i = 1; i <= m; i++){
scanf("%d %d %d",&a,&b,&c);
v[a][b] = min(c,v[a][b]);
}
dijkstra(x);//x是起点
int tt;
//反向建图
for(int i = 1; i <= n; i++){
for(int j = 1; j < i; j++){
tt = v[i][j];
v[i][j] = v[j][i];
v[j][i] = tt;
}
}
dijkstra(x);
int sum = 0;
for(int i = 1; i <= n; i++){
sum = max(dist[i] + tem[i],sum);
}
printf("%d\n",sum);
return 0;
}