这个题目的意思就是许多农场之间被单方向通道连接,取其中一点,求其余每个农场的牛到这个农场来回的最短距离中,最大的那个距离。刚刚开始我理解错了题目的意思,没有看到是来回最短距离,所以一直错误。最后看清题目才想到了方法。
既然是所有的点到其中一个固定点的最短距离,那么对这个固定点进行一次Dijkstra算法,就可以求每个牛回家的最短距离,如果在输入的时候把所有的边反转过来再构建一个图,那么还是对这个固定点进行一次Dijkstra算法,不就等同于求出了每头牛去的时候的最短距离,再来一次循环就能找出这个最大值了。
One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.
Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.
Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?
Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2.. M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
Sample Input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
Sample Output
10
Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
#include <iostream>
#include <stdio.h>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
#define Max_N 1005
#define INF 0x3f3f3f3f;
int dist1[Max_N];
int vist[Max_N];
int vist1[Max_N];
int dist2[Max_N];
int N, M, X;
int a, b ,c;
struct edge {
int to, w;
edge(int x = 0, int y = 0):to(x), w(y){}
};
struct point {
int f;
int s;
point (int x = 0, int y = 0):f(x), s(y){}
bool operator <(const point r) const {
return s > r.s;
}
};
vector<edge> E[Max_N];
vector<edge> G[Max_N]; //初始化两个图
void diskstra(int s,int *dist) {
priority_queue<point> que;
for (int i = 1; i <= N; i++)
dist[i] = INF;
memset(vist, 0, sizeof(vist));
dist[s] = 0;
que.push(point(s, 0));
while (!que.empty()) {
point p = que.top();
que.pop();
int v = p.f;
if (vist[v]) continue;
vist[v] = true;
for (int i = 0; i < E[v].size(); i ++) {
edge e = E[v][i];
if (!vist[e.to] && dist[e.to] > dist[v] + e.w) {
dist[e.to] = dist[v] + e.w;
que.push(point(e.to, dist[e.to]));
}
}
}
}
int main()
{
scanf ("%d%d%d", &N, &M, &X);
for (int i = 0; i <= N; i++)
E[i].clear();
for (int i = 0; i < M; i++) {
scanf ("%d%d%d", &a, &b, &c);
E[a].push_back(edge(b,c));
G[b].push_back(edge(a,c)); //输入的时候 分别输入到两个图中。
}
int max1 = 0;
diskstra(X,dist1);
diskstra(X,dist2); //进行两次计算,再下面一次循环就可以得到答案了。
for (int i = 1; i <= N; i++) {
if (dist1[i] + dist2[i] > max1) max1 = dist2[i] + dist1[i];
}
printf("%d\n", max1);
return 0;
}