(Jizhong)가 1595은 [트레이닝] GDKOI은 (수신자)] Floyed 통행료

(파일 IO) : 입력 : toll.in 출력 : toll.out의
시간 제한 : 1000 밀리 공간 제약 : 26만2천1백44킬로바이트의 특정 제한
고토 ProblemSet


제목 설명
다른 사람들과는 농부 존 오히려 나에게 가축의 세계에 부정적인를 가르 칠 것, 시도 내 큰, 낮과 밤의 부정적인 정신 중지가 가축의 세계는 돈을 버는 방법을 제공합니다. 돈을 만들기 위해, 그는 농장 도로 통행료 걷고있는 소는 농부 요한에게 인계해야한다 있도록 규칙 및 규정의 시리즈를 설정합니다.

N 양식장 (N을 1 번째) (1 <= N <= 250) 초원하고있는 M (1 <= M <= 10000) 양방향 도로 구간 잔디 A_j 및 B_j (1 <= A_j <= N 1 <= B_j <= N). 젖소는 잔디 초원 중 하나에서 이탈이 도달 할 수 있습니다. FJ는 유료 도로는 양방향 L_j A_j 그리고 B_j (1 <= L_j <= 10)를 통해 연결되어 제공했다.

가능한 같은 두 초원을 연결하는 도로의 수 있지만, 거기 초원 잔디를 연결하는 어떤 길도없고이 자체. 좋은 뉴스는 잔디의에서 ​​대부분의 소, 경로의 시리즈를 통해, 당신은 항상 초원의 다른 도달 할 수 있다는 것입니다.

탐욕에 더하여, 우리는 무슨 말을 해야할지하지 않습니다. 심지어 상기 각각 FJ도 초원 구비하는 C_I를 통행료 (1 <= C_I <= 100000). 비용의 다른 부분에 잔디 초원에서, 모든 도로 통행료 최대 통행료 플러스 (시작과 끝을 포함하여) 모든 잔디 통과의 결과입니다.

그들이 그 경로를 선택해야하는지 조사하려는 노력 소. 그들은 당신이 K (1 <= K <= 10,000) 문제와 도전에 대응하는 출력 당 최소 비용을 허용하는 프로그램을 작성합니다. 잔디의 시작과 끝을 나타내는, 상기 i 번째 문제는 두 숫자와 s_i t_i를 (1 <= t_i <= N = ;! S_i t_i 1 <= s_i <= N)를 포함한다.

다섯 잔디를 포함하는 다음 샘플 이미지 고려해
그림 삽입 설명 여기
도로에서 통행료 초원 잔디 3 '측에 "3"유료 포인트 "5 2 초원.

1은 잔디 잔디 (13)에서 올 수 있습니다, 잔디 잔디 4에서 온 그리고 마침내 도착한 잔디 잔디 4 5 갔다. 그래서 가면 필요 '측 통행료는 "2 + 1 + 1 = 4, 총 비용은 4 + 4 = 8 정도로 점, 통행료 4 (잔디 포인트 5 통행료 최대) 할 필요가있다.

가장 좋은 경로가 2에서 잔디 2에서 3 잔디 잔디이며, 5 잔디, 잔디에 도착하고 마지막 3. 그래서 가장자리에 대한 통행료, 갈 3 + 1 = 4, 5 점 - 사망자가 5 + 4 = 9의 총 비용입니다.


입력
라인 (1) : N, M 및 K : 세 공간 정수 분리
제 행 I + 1은 하나의 정수를 포함 : N + 1 개 라인을 통해 제 C_I
제 N의를 + 2 내지 N + M + 1 : 광고 J + N + 1 라인은 세 개의 정수 공백으로 구분 포함 A_j, B_j L_j 및
반전 제 N + M + 2 제 N + M + K + 1 행 I + N + M + 1 행 나타내고, 제 i 번째의 문제는 두 공간은 정수 및 s_i t_i 의해 분리 포함

출력
K 라인 내지 제 : i 번째 행은 t_i에서 s_i에 최소 비용을 나타내는 하나의 정수를 포함한다.


샘플 입력
. 제 7 2
2
. 5
. 3
. 3
. 4
. 1 2 3
. 1 3 2
2 3 5
. 3. 제 1
. 제 1 4
2 3 4
. 3 4 4
. 1 4
2 3

샘플 출력
. 8
. 9


데이터 범위 제한


문제 해결 아이디어
멀티 소스 최단 경로 문제는 데이터의 작은 범위는, 당신이 사용할 수있는 것은 분명하다 에프 플로이드 프로세스 알고리즘,
최단 경로가 올바른 경로의 최대 점에 관한 이후 어떻게 빠른 상태 전이 결정 단계, 최대 경로 중량의 점에서의 결과는이 문제의 주요 고려 사항이다. 모든 권리는 점을 열거 할 경우, 복잡성은 분명히 폭발입니다.
우리는 또 다시 리콜 에프 플로이드 알고리즘이 작동한다 :
직접 및 중간 인터페이스 의하여 : I은 J로, 두 가지 가능성이 존재 케이 케이 , 소요 미디엄 나는 나를 라인에
우리가 얇은 아래로 더보고 싶다, 케이 케이 인터페이스의 중간이고, 케이 케이 열거 순서는 임의적이다?
명백히 임의! 이 돌파구 : 우리가 변덕을 수정할 수 있습니다 케이 케이 열거 순서를! 따라서이 문제는 해결 될 것입니다.
우리는 교통 요점은 큰 번호를 다시 매기, 작은에서 무게를 누릅니다 케이 케이 대표는 포인트 번호를 다시 부여한다 케이 케이 큰 오른쪽 점 더 큰
우리가 필요로 큰 교통 지점에 작은 열거 할 케이 케이 는 때문에 케이 케이 큰 소형의 열거입니다
우리가 찾고있는 나는 , 제이 I, J 경우에만 열거 할 우리 통과 점 사이의 최단 경로, 케이 케이 우리의 현재를 설명하고, 나는 , 제이 I, J 이상 없음 약간 오른쪽의 사이의 최단 케이 케이 바로 마지막 위대한 작은 반점을 케이 케이 즉로서 나는 - > 제이 I-> J 경로에 추가 나는 , 제이 I, J 최대 오른쪽 외부 점,
다음 캔을 실행 에프 flyod 경로의 최대 포인트는 옳은 나는 , 제이 , 케이 I, J, K 우측의 최대 값의 중앙으로 3 점!


코드

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,K,b[260],p,q,dis[260][260],ans[260][260];
struct c{
    int x,y;
}a[260];
bool cmp(const c&l,const c&r){
    return l.x<r.x;
}
int main(){
   freopen("toll.in","r",stdin);
   freopen("toll.out","w",stdout);
    scanf("%d%d%d",&n,&m,&K);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].x);
        a[i].y=i;
    }
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
        b[a[i].y]=i;
    memset(dis,INF,sizeof(dis));
    for(int i=1;i<=n;i++)
        dis[i][i]=0;
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        dis[b[u]][b[v]]=dis[b[v]][b[u]]=min(dis[b[u]][b[v]],w);
    }
    memset(ans,INF,sizeof(ans));
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(i==j)
                 continue;
               dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
              if(dis[i][j]==dis[i][k]+dis[k][j])
                    ans[i][j]=min(ans[i][j],dis[i][j]+max(a[i].x,max(a[j].x,a[k].x)));
                    
            }
    for(int i=1;i<=K;i++)
    {
         scanf("%d%d",&p,&q);
         printf("%d\n",ans[b[p]][b[q]]);
    }
}
게시 된 119 개 원래 기사 · 원 찬양 8 · 전망 4910

추천

출처blog.csdn.net/kejin2019/article/details/104978499