ポータル
Portal1:Luogu
Portal2:CONCEPT
説明
N農場のそれぞれから一つの牛\((1 \ルN \ル1000)\)便利番\(Nは\ 1 \ cdots)の大きな牛のパーティーに出席しようとしている、ファーム#Xで開催される(1 \ \(ルX \ルN)\) 。合計\(M(1 \ルM \ル10万)\)単方向(一方向の道路が農場の対を接続し、道路\は、(iは\)が必要\(T_I(1 \ルチタン\ル100)\)ユニットトラバースする時間。
それぞれの牛はパーティーが終わったとき、彼女の農場に戻って、パーティーに歩いている必要があります。それぞれの牛は怠け者であるため、最短時間で最適なルートを選びます。道路が一方通行なので牛の復路は、相手に自分の本来のルートと異なる場合があります。
すべての牛、牛は党とバックに歩い費やす必要があり、時間の最長の量は何ですか?
冬には、\(N \)牛が出席しなければならないの番号\(X- \)(\ (X-ル\ルN \)\ 1農場の牛のパーティが開催された)(\(1ル\ N \ル1000は、\) )、ファーム間である(\ M \)(\ (1ルM \ \ 100000ル\) )道路区間、各経路長有するチタン\)の\((\ ル\(。1チタン\ル100 \) )。
パーティーに出席した各牛はいずれかの当事者に、家に帰るか、家に帰る必要があります後、それぞれの牛は、最長経路長の(前後に)N牛のための最短経路を最短パスを選択します。
入力
三つの整数の最初の行\(N \)、\ (M \)、\ (X- \) 。
2行目の\(M + 1 \)行:各ラインは三つの整数有する\(a_iを\)、\ (B_i \)、\ (T_I \)を、から発現\(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
その上で(バック歩く、歩く)を2回最短経路を計算し、最終的には牛が道路の反対側を取るために必要なもの、決定後、問題が解決され、最長です。
コード
#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;
}