「Luogu 1821」[USACO07FEB]シルバーブルパーティーシルバー牛パーティー

より良い読書体験

ポータル

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;
}

おすすめ

転載: www.cnblogs.com/shenxiaohuang/p/11594332.html