其他牛先从自己家走到x牛家,再从x牛家走回自己家,问这些牛走的最长路。开始我幼稚的遍历了每个点做dijkstra,不出意外TLE了。其实一头牛经过一段路到了x,我们只需要将所有有向路反向,再从x找其他点的最短路,就是其他点到x的最短路。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<sstream>
#define ll long long
using namespace std;
/**********************************************************/
const int N_MAX = 1000+10;
const int INF = 0x00ffffff;
const double M_DBL_MAX = 1.7976931348623158e+308;
const double M_DBL_MIN = 2.2250738585072014e-308;
int n;
int maps[N_MAX][N_MAX];
int d[N_MAX],vis[N_MAX],dsum[N_MAX];
/**********************************************************/
int min_2 (int x,int y) {return x<y?x:y;}
int max_2 (int x,int y) {return x>y?x:y;}
void swap (int& a, int& b){a^=b;b^=a;a^=b;}
void dijkstra (int x);
/**********************************************************/
int main()
{
//freopen ("in.txt","r",stdin);
int m,x;
while(scanf ("%d%d%d",&n,&m,&x)!=EOF)
{
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
maps[i][j]=(i==j?0:INF);
int a,b,c;
for (int i=0;i<m;i++){
scanf ("%d%d%d",&a,&b,&c);
maps[a-1][b-1]=c;
}
dijkstra (x-1);
for (int i=0;i<n;i++)
dsum[i]=d[i];
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
swap (maps[i][j],maps[j][i]);
dijkstra (x-1);
int x=0;
for (int i=0;i<n;i++){
dsum[i]+=d[i];
if (x<dsum[i])
x=dsum[i];
}
printf ("%d\n",x);
}
return 0;
}
void dijkstra (int z)
{
memset (vis,0,sizeof (vis));
for (int i=0;i<n;i++)
d[i]=(i==z?0:INF);
for (int i=0;i<n;i++){
int x,m=INF;
for (int y=0;y<n;y++)
if (!vis[y]&&d[y]<m)
m=d[x=y];
vis[x]=1;
for (int y=0;y<n;y++)
d[y]=min_2 (d[y],d[x]+maps[x][y]);
}
}