思路:题目意思是给出n个点和m条有向边,和起点x,求从x到i点的最短距离加上i点回到x点的最短距离之和的最大值。
因此只需要
正向存图,求x到其他点的最短距离;
反向存图,求其他点到x的最短距离;
把每个点的最短距离求和求Max就是答案。
dijkstra堆优化版
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010, M = 1e6;
int n,m,x;
int h[N],w[M],e[M],ne[M],idx;
int rh[N],rw[M],re[M],rne[M],ridx;
int dist[N],backup[N];
bool st[N];
void add(int a,int b,int c){
e[idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx++;
re[ridx] = a; rw[ridx] = c; rne[ridx] = rh[b]; rh[b] = ridx++;
}
void dijkstra(int k){
memset(dist,0x3f,sizeof dist);
memset(st,0,sizeof st);
if(k == 2){
memcpy(h,rh,sizeof rh);
memcpy(w,rw,sizeof rw);
memcpy(e,re,sizeof re);
memcpy(ne,rne,sizeof rne);
}
dist[x] = 0;
priority_queue<PII,vector<PII>,greater<PII> > q;
q.push(make_pair(0,x));
while(q.size()){
PII t = q.top(); q.pop();
int u = t.second, distance = t.first;
if(st[u]) continue;
st[u] = true;
for(int i = h[u]; ~i; i = ne[i]){
int j = e[i];
if(dist[j] > distance + w[i]){
dist[j] = distance + w[i];
q.push(make_pair(dist[j],j));
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&x);
memset(h,-1,sizeof h);
memset(rh,-1,sizeof rh);
for(int i = 0; i < m; i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
dijkstra(1);
memcpy(backup,dist,sizeof dist);
dijkstra(2);
int res = 0;
for(int i = 1; i <= n; i++) res = max(res,backup[i] + dist[i]);
printf("%d",res);
return 0;
}