(Jizhong)1595. [トレーニング] GDKOI通行料(有料)] [Floyed

(ファイルIO):入力:toll.in出力:toll.outの
制限時間:1000ミリ秒のスペースの制約:262144キロバイトの特定の制限
後藤ProblemSet


タイトル説明
他の皆と、ファーマージョンはむしろ私の偉大な、昼と夜の負の精神オフと呼ばれる牛の世界はお金を稼ぐ方法を思い付くしようとしている、私の牛の世界への負を教えてくれる。幸運を作るために、彼は農場道路通行料で歩いてどの牛がファーマージョンに引き渡されるべきように規則や規制のシリーズを設定します。

N(1 <= N <= 250)草原(Nまで番号1)、及びM(1 <= M <= 10000)双方向道路リンク草A_jとB_j(1 <= A_j <=を有していることにより、ファームN 1 <= B_j <= N)。牛は草が茂った草原のいずれかからの任意の逸脱に到達することができます。FJ(1 <= L_j <=10万)の双方向L_j A_jとB_jを介して接続されている有料道路を提供しています。

可能性のある同じ2つの牧草地を結ぶ道路の数が、草原の草と、この自分自身を結ぶ全く道はありません。良いニュースは、芝生のいずれかから、ほとんどの牛は、パスの一連の、あなたは常に牧草地の他に達することができるということです。

貪欲に加えて、我々は言うことを知りません。上記の各々におけるFJも牧草地が設けられていることC_Iを通行料(1 <= C_I <= 100000)。コストの別の部分に草が茂った草原からは、すべての道路通行料、最大の通行料プラスの(開始と終了を含む)すべての草通過の結果です。

彼らはその道を選ぶべきかを調査するハードワーキング牛。彼らはあなたがK(1 <= K <= 10,000)の問題と挑戦に対応する出力あたりの最小コストを受け入れるプログラムを書きたいです。芝生の開始と終了を示し、(1 <= T_I <= N ;! S_I = T_I 1 <= S_I <= N)、i番目の問題は、二つの数とS_I T_Iを含みます。

5本の草を含む以下のサンプル画像を検討:
ここに画像を挿入説明
道路からの通行料の草原草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:3つの空間は、整数を分離:N、MおよびKの
Nを介して第2 + 1行:C_I:最初の行I + 1は、単一の整数含ま
N + M + 1への第一のN + 2 :ラインj + N + 1ラインは、三の整数スペースで区切ら含ま:A_j、B_j L_j及び
反転された第1のN + M + 2第N + M + K + 1:回線I + N + M + 1行整数によって分離し、S_I T_I I番目の質問は、2つのスペースを含む意味

出力
K線に最初の:i番目の行はT_IからS_I最小コストを表す、単一の整数を含んでいます。


サンプル入力
5. 7 2
2
。5
。3
。3
。4
。1 2 3
。1 3 2
2 5 3
。5 3.1
5 1.4
2 4.3
3 4 4
。1 4
2 3

サンプル出力
。8
。9


データ範囲の制限


問題解決のアイデア
マルチソース最短経路問題は、データの小さな範囲では、あなたが使用できることは明らかです F リットル インクルード D フロイド 処理にアルゴリズム、
最短パスが正しいパスで最大点に関連しているので、どのように高速状態遷移の決定段階、最大経路重みの点における結果は、この問題のコア考慮事項です。すべての権利は、ポイントを列挙した場合、複雑さは明らかに爆発です。
私たちは再び、再びリコール F リットル インクルード D フロイド アルゴリズムが動作する:
直接中間インターフェースによって:I jに、2つの可能性があります K K 、とり メートル n個 私に 行に
、我々は薄いダウン、さらに見てみたいです、 K K インターフェースの中央を表し、そして K K 列挙順序は任意ですか?
明らかに、任意の!この中に突破口:私たちは理不尽を変更することができ K K 列挙順序!したがって、この問題は解決されます。
我々は通過点で大きなリナンバリングに小さなから重みをタップします K K 代表は、点を再番号付けされています K K 大きい、大きい右のポイント
私たちは大きな通過点に小さな列挙する必要があります K K 、なぜなら K K 大小規模の列挙です
、我々が探しています J I、J の場合のみ列挙するために、我々の通過ポイントとの間の最短経路、 K K 私たちの現在を説明し、 J I、J 以上の無権利少しの間の最短 K K 右の最後の偉大な小さなスポット K K 即ちとして - > J I-> J パスに加え、 J I、J 最大外右ポイント、
缶を実行するために、その後、 F リットル インクルード D flyod 経路上の最大ポイントが右であります J K 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