题意:求一点到某一点的最短距离和回来的最短距离之和中的最大值。
思路:对出边和入边构造的图分别求一次最短路径,两次dist数组相加,取最大值。
代码:
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int inf = 1000000000;
const int maxn = 1005;
const int maxm = 1000005;
struct node{
int v;
int w;
node(int _v, int _w){v = _v; w = _w;}
};
struct arc{
int u,v;
int w;
};
int n,m,x;
int dist[maxn]; //记录单源最短路径
int ans[maxn]; //存储结果
bool inq[maxn]; //判断节点是否入队
arc a[maxm]; //存储边
vector<node> list[maxn]; //邻接链表
queue<int> q;
void Input(){
for(int i = 0; i < m; i++){
cin>>a[i].u>>a[i].v>>a[i].w;
}
}
void spfa(int s){
for(int i = 1; i <= n; i++){
dist[i] = inf;
inq[i] = false;
}
dist[s] = 0;
q.push(s);
while(!q.empty()){
int u = q.front(); q.pop();
inq[u] = false;
for(int i = 0; i < list[u].size(); i++){
int v = list[u][i].v;
if(dist[u] + list[u][i].w < dist[v]){
dist[v] = dist[u] + list[u][i].w;
if(!inq[v]) {q.push(v); inq[v] = true;}
}
}
}
}
void Solve(){
int maximum = -inf;
int sum = 0;
for(int i = 1; i <= n; i++) ans[i] = 0;
//求所有点到x的最短距离
for(int i = 1; i <= n; i++) list[i].clear();
for(int i = 0; i < m; i++) list[a[i].v].push_back(node(a[i].u,a[i].w));
spfa(x);
for(int i = 1; i <= n; i++) ans[i] += dist[i];
//求x到所有点的最短距离
for(int i = 1; i <= n; i++) list[i].clear();
for(int i = 0; i < m; i++) list[a[i].u].push_back(node(a[i].v,a[i].w));
spfa(x);
for(int i = 1; i <= n; i++) ans[i] += dist[i];
//找到最大值
for(int i = 1; i <= n; i++)
if(ans[i] > maximum)
maximum = ans[i];
cout<<maximum<<"\n";
}
int main(){
while(cin>>n>>m>>x){
Input();
Solve();
}
return 0;
}