#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <algorithm> #include <iostream> using namespace std; #define maxn 1011 #define INF 1000000000 int n; int e[maxn][maxn],f[maxn][maxn],s[maxn],d1[maxn],d2[maxn]; void dij1(int x) { int i,j,k,u,v; for(i=1;i<=n;i++) { s[i]=0;d1[i]=e[x][i]; } s[x]=1; for(i=1;i<n;i++) { int min_d=INF,p; for(j=1;j<=n;j++) { if(!s[j]&&d1[j]<min_d) { min_d=d1[j]; p=j; } } s[p]=1; for(k=1;k<=n;k++) { if(!s[k]&&e[p][k]+d1[p]<d1[k]) d1[k]=e[p][k]+d1[p]; } } } void dij2(int x) { int i,j,k,u,v; for(i=1;i<=n;i++) { s[i]=0;d2[i]=f[x][i]; } s[x]=1; for(i=1;i<n;i++) { int min_d=INF,p=0; for(j=1;j<=n;j++) { if(!s[j]&&d2[j]<min_d) { min_d=d2[j]; p=j; } } s[p]=1; for(k=1;k<=n;k++) { if(!s[k]&&f[p][k]+d2[p]<d2[k]) d2[k]=f[p][k]+d2[p]; } } } int main() { int m,x; while(scanf("%d%d%d",&n,&m,&x)!=EOF) { int i,j,k,a,b,c; for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i==j)e[i][j]=f[i][j]=0; else e[i][j]=f[i][j]=INF; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); e[a][b]=min(c,e[a][b]); f[b][a]=min(c,f[b][a]); } /*for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cout<<f[i][j]<<" "; cout<<endl; }*/ dij1(x); dij2(x); int ans=0; for(i=1;i<=n;i++) { //cout<<d2[i]<<" "; ans=max(d1[i]+d2[i],ans); } printf("%d\n",ans); } return 0; } /* 记s[i]为从i点到x的最短距离+从x点到i的最短距离,题意要求的是max(s[i]) 如果枚举n个点,求最短路到x,时间复杂度要O(n^3),所以不可取。 由于道路是单向,用数组记录相反方向求最短路,求出的最短路就是各点到x的最短路。 再求正常情况下x到各点的最短路就好了。 最短路用dijkstra即可 */