문
PLATFORM1 : 게릴라 대원
포털 2 : Luogu
기술
N 농장에서 각각 한 소 \ ((1 \ 르 N \ 르 1000) \) 편리 번호 \ (N은 \ 1 \ cdots) 큰 소 파티에 참석하는 것입니다 농장 #X에서 개최되는 (1 \ \ ( 제작 : X \ 르 N) \) . 총 \ (M (1 \ 르 M \ 르 100,000) \) 단방향 (일방향 도로 농장 쌍 연결;도 \ (나는 \) 필요 \ (T_i를 (1 \ 르 티 \ 르 100) \) 단위 시간을 통과합니다.
각각의 소는 당사자가 끝나면, 그녀의 농장으로 돌아가 파티에 걸어해야합니다. 각 소 지연되고, 따라서 짧은 시간에 최적의 경로를 선택합니다. 도로가 편도 때문에 젖소의 반환 경로는 파티에 그녀의 원래 경로 다를 수 있습니다.
모든 소, 소가 당과 뒷면에 걸어 지출해야하는 시간이 가장 긴 금액은 무엇인가?
겨울에, \ (N \) 소에 참석하기 위해이 번호가 매겨진 \ (X 축 \) (\ 합니다 (X-르 \ 르 N \) \ 1 농장 가축의 파티 개최) ( \ (1 르 \ N \ 르 1000 \) ), 팜 사이가 (\ M \) (\ . (1 르 M \ \ 100000 르 \) ) 도로 구간 각각의 통로 길이를 갖는 티타늄 \)의 \ ( (\ 르 (\. 1 티 \ 르 100 \) ).
어느 파티에, 집 또는 집에 가야 파티에 참석 한 각 젖소 후, 각 젖소는 최단 경로 (앞뒤) 가장 긴 경로 길이의 N 소에 대한 최단 경로를 선택합니다.
입력
세 개의 정수의 첫 번째 행 \ (N \) \ (M \) \ (X- \) ;
의 두 번째 행 \ (M + 1 \) 라인 각 라인은 세 개의 정수 갖는다 \ (A_I \) \ (B_i \) \ (T_i을 \) , A로부터 발현 \ (A_I \) 팜한다 (\ b_i \) 도로 농장, 길이 \ (T_i \) .
산출
가능한 가장 긴 최단 경로의 길이를 나타내는 정수입니다.
샘플 입력
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
샘플 출력
10
힌트
해결책
지점에 와서 소 제목의 일부를 보자, 그리고 그 시점 다시 최대의 짧은에서 이동합니다. 그래서 우리는 직접 dijkstra
(도보 다시 걸을) 거기에, 그리고 마지막으로 소 한 후 문제가 해결되고, 도로의 다른 쪽 끝이 가장 긴 취할 필요 어떤 결정을 두 번 최단 경로를 계산합니다.
암호
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f, MAXN = 200005;
struct EDGE {
int nxt, to, val;
} edge[MAXN];
int n, m, S, cnt, U[MAXN], V[MAXN], VAL[MAXN], dis[MAXN], dist[MAXN], head[MAXN];
bool vis[MAXN];
inline void addedge(int u, int v, int val) {//邻接表存图
edge[++cnt].to = v; edge[cnt].val = val; edge[cnt].nxt = head[u]; head[u] = cnt;
}
inline void dijkstra(int S) {//dijkstra最短路
memset(dis, INF, sizeof(dis));
priority_queue< pair<int, int> > Q;
Q.push(make_pair(0, S));
dis[S] = 0;
while (!Q.empty()) {
int u = Q.top().second;
Q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].to;
if (dis[v] > dis[u] + edge[i].val) {
dis[v] = dis[u] + edge[i].val;
Q.push(make_pair(-dis[v], v));
}
}
}
}
int main() {
scanf("%d%d%d", &n, &m, &S);
memset(head, -1, sizeof(head));
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &U[i], &V[i], &VAL[i]);
addedge(U[i], V[i], VAL[i]);//正向建图
}
dijkstra(S);
for (int i = 1; i <= n; i++)
dist[i] = dis[i];//记录走到目标点的路程
cnt = 0;
memset(edge, 0, sizeof(edge));
memset(vis, 0, sizeof(vis));
memset(head, -1, sizeof(head));//注意清空数组
for (int i = 1; i <= m; i++)
addedge(V[i], U[i], VAL[i]);//反向建图
dijkstra(S);
int Max = -INF;
for (int i = 1; i <= n; i++)
Max = max(Max, dis[i] + dist[i]);//判断那个奶牛是走得最多的
printf("%d\n", Max);
return 0;
}