/*
translation:
给出一张图,给出图中的一个点。求图中其它点到该点并回到原点的最长距离是多少?
solution:
dijkstra算法
首先可以很容易求出从x到其它点的最小距离。然后求其它点到x的最小距离可以将图中所有的边反向
然后求x到其它点的最小距离。如此只需要求两次即可。
note:
1:本来以为无脑的对每一个点dijkstra会超时,没想到无脑的暴力dijkstra依然能过。但是明显这种方法更好。
*拆点,加点,加边,加反向边这几种技巧是图论中经常见到的
date:
2016.10.18
*/
#include <iostream>
#include <cstdio>
#include <utility>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 1000 + 5;
const int INF = 1e8;
struct Edge
{
int to, cost;
Edge(int to_ = 0, int cost_ = 0):to(to_),cost(cost_){}
};
typedef pair<int, int> P;
int n, m, x;
vector<Edge> G[maxn];
vector<Edge> rG[maxn];
int d[maxn],rd[maxn];
void dijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > pq;
fill(d, d+n+1, INF);
d[s] = 0;
pq.push(P(0, s));
while(!pq.empty())
{
P p = pq.top(); pq.pop();
int v = p.second;
if(d[v] < p.first) continue;
for(int i = 0; i < G[v].size(); i++)
{
Edge e = G[v][i];
if(d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
pq.push(P(d[e.to], e.to));
}
}
}
}
void reDijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > pq;
fill(rd, rd+n+1, INF);
rd[s] = 0;
pq.push(P(0, s));
while(!pq.empty())
{
P p = pq.top(); pq.pop();
int v = p.second;
if(rd[v] < p.first) continue;
for(int i = 0; i < rG[v].size(); i++)
{
Edge e = rG[v][i];
if(rd[e.to] > rd[v] + e.cost)
{
rd[e.to] = rd[v] + e.cost;
pq.push(P(rd[e.to], e.to));
}
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%d%d%d", &n, &m, &x))
{
for(int i = 0; i <= n; i++)
{
G[i].clear();
rG[i].clear();
}
int s, t, c;
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &s, &t, &c);
G[s].push_back(Edge(t, c));
rG[t].push_back(Edge(s, c));
}
dijkstra(x);
reDijkstra(x);
int ans = -1;
for(int i = 1; i <= n; i++)
{
if(i != x) ans = max(ans, d[i] + rd[i]);
}
printf("%d\n", ans);
}
return 0;
}
poj3268(最短路,dijkstra)
最新推荐文章于 2020-04-26 13:15:22 发布
