「POJ 3268」실버 암소 파티

더 나은 독서 경험

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

추천

출처www.cnblogs.com/shenxiaohuang/p/11594299.html