Description
小 S 想要从某地出发去同学k的家中参加一个 party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多少,这个任务就交给了你。
分析:
单源最短路问题,去K点的距离用反图处理即可。
代码如下:
#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int inf=10000000;
int rmap[1001][1001],map[1001][1001],n,m,k,dist[1005],dist1[1005]; //rmap是反图
bool vis[1005];
queue<int>q;
vector<int>out[1001]; //出度;
vector<int>in[1001]; //入度,即反图的出度;
void input(){
int x,y,z,i,j;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i!=j)rmap[i][j]=inf,map[i][j]=inf;
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
if(map[x][y]==inf)out[x].push_back(y);
if(rmap[y][x]==inf)in[y].push_back(x);
map[x][y]=min(map[x][y],z);
rmap[y][x]=min(rmap[y][x],z);
}
}
int solve(){ //两次SPFA
int i,j,ans=-inf;
for(i=1;i<=n;i++)dist[i]=inf;
dist[k]=0;
q.push(k);
vis[k]=true;
while(!q.empty()){
int cur=q.front();
q.pop();
vis[cur]=false;
for(i=0;i<in[cur].size();i++)
if(dist[cur]+rmap[cur][in[cur][i]]<dist[in[cur][i]])
{
dist[in[cur][i]]=dist[cur]+rmap[cur][in[cur][i]];
if(!vis[in[cur][i]]){
q.push(in[cur][i]);
vis[in[cur][i]]=true;
}
}
}
memset(vis,0,sizeof(vis)); //清零vis
for(i=1;i<=n;i++)dist1[i]=inf;
dist1[k]=0;
q.push(k);
vis[k]=true;
while(!q.empty()){
int cur=q.front();
q.pop();
vis[cur]=false;
for(i=0;i<out[cur].size();i++)
if(dist1[cur]+map[cur][out[cur][i]]<dist1[out[cur][i]])
{
dist1[out[cur][i]]=dist1[cur]+map[cur][out[cur][i]];
if(!vis[out[cur][i]]){
q.push(out[cur][i]);
vis[out[cur][i]]=true;
}
}
}
for(i=1;i<=n;i++)
if(dist[i]!=inf&&dist1[i]!=inf) ///注意要判断是否连通;
ans=max(ans,dist[i]+dist1[i]);
printf("%d\n",ans);
}
int main(){
input();
solve();
}