#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即可
*/
poj 3268 Silver Cow Party 最短路/dijkstra
最新推荐文章于 2021-04-01 18:48:34 发布