题意:有N个点M条边,农场间由M条有向路径连接。每头牛来回都走最短的路,求这些牛中来回的最大时间?
分析:做两次spfa,一次以X为源点到每头牛,再一次从每头牛到X,求出每头牛来回的最大时间即使答案。
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<cstdio>
const int INF=0x3f3f3f3f;
typedef long long LL;
using namespace std;
const int maxn=100005;
struct Edge
{
int e,w;
Edge(){}
Edge(int _e,int _w):e(_e),w(_w){}
};
int dist[maxn];
int vis[maxn];
vector<Edge> G[maxn];
int N,M,X;
int spfa(int v,int e)
{
memset(dist,INF,sizeof(dist));
memset(vis,0,sizeof(vis));
queue<int> q;
dist[v]=0;
q.push(v);
vis[v]=1;
while(!q.empty())
{
int s=q.front();q.pop();
vis[s]=0;
for(int i=0;i<G[s].size();i++)
{
int e=G[s][i].e;
if(dist[s]+G[s][i].w<dist[e])
{
dist[e]=dist[s]+G[s][i].w;
if(!vis[e])
{
vis[e]=1;
q.push(e);
}
}
}
}
return dist[e];
}
int main()
{
// freopen("E:\\ACM\\test.txt","r",stdin);
scanf("%d%d%d",&N,&M,&X);
int s,e,w;
for(int i=0;i<=N;i++) G[i].clear();
for(int i=0;i<M;i++)
{
scanf("%d%d%d",&s,&e,&w);
G[s].push_back(Edge(e,w));
}
int ans=0;
for(int i=1;i<=N;i++)
{
if(i==X) continue; //不包括X自身那头牛
int a=spfa(X,i); //X到每头牛的距离
int b=spfa(i,X); //每头牛到X的距离
ans=max(ans,a+b); //求每头牛来回的最大值
}
printf("%d\n",ans);
return 0;
}