题目链接: PO—3268 Silver Cow Party
题目大意: 给一个有向图,求所有点经过定点s在回到自身的最短路中的最大距离。
题目分析: 先求从s出发的最短路,然后把所有边反向,再求回到s的最短路,用dijkstra就OK了
/***********************************
Problem: 3268 User: ChenyangDu
Memory: 4176K Time: 79MS
Language: C++ Result: Accepted
************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct edge{int l,v;};
edge Edge(int l,int v){
edge t;
t.l = l;
t.v = v;
return t;
}
bool operator < (edge a,edge b){
return a.l>b.l;
}
const int maxn = 1005,INF = 1000000;
int n,m,x,G[maxn][maxn],d[2][maxn];//d[0]是从s出发的,d[1]是回到s的
int main(){
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&m,&x);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
G[i][j] = INF;
d[0][i] = d[1][i] = INF;
}
for(int a,b,t,i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&t);
if(G[a][b] == INF || G[a][b] > t)
G[a][b] = t;
}
priority_queue <edge> que;
que.push(Edge(0,x));
d[0][x] = 0;
while(!que.empty()){
edge t = que.top();
que.pop();
if(t.l > d[0][t.v])continue;
for(int i=1;i<=n;i++){
if(i!=t.v && G[t.v][i]!=INF){
if(d[0][i] > d[0][t.v] + G[t.v][i]){
d[0][i] = d[0][t.v] + G[t.v][i];
que.push(Edge(d[0][i],i));
}
}
}
}
d[1][x] = 0;
que.push(Edge(0,x));
while(!que.empty()){ //这次把G倒着写就行了
edge t = que.top();
que.pop();
if(t.l > d[1][t.v])continue;
for(int i=1;i<=n;i++){
if(i!=t.v && G[i][t.v]!=INF){
if(d[1][i] > d[1][t.v] + G[i][t.v]){
d[1][i] = d[1][t.v] + G[i][t.v];
que.push(Edge(d[1][i],i));
}
}
}
}
int ans = 0
for(int i=1;i<=n;i++){
ans = max(ans,d[0][i] + d[1][i]);
}
cout<<ans<<endl;
fclose(stdin);
return 0;
}