yukicoder contest 1(No.1)解説

yukicoder
yukicoder
競技プログラミングの練習サイト

yukicoder埋めも少しずつやっていきたいので、始めます。
1297問、解き尽くしたいですね~。

No.1 道のショートカット

No.1 道のショートカット - yukicoder
競技プログラミングの練習サイト

N個の町とM本の道。
道にはコストYと時間Mがある。
1→Nの経路の中で、通った道のコストがY以下になるものの中で最小を求めよ。

見た通り、ダイクストラっぽい問題です。
ただ、コストを合計Y以下にしないといけないため、ダイクストラをするときにコストの情報を持たせる必要があります。

#include<bits/stdc++.h>
//#include<atcoder/all>

using namespace std;
//using namespace atcoder;

int main(){
    int N;
    int C;
    int V;
    cin>>N>>C>>V;
    int S[V],T[V],Y[V],M[V];

    for(int i=0;i<V;i++){
        cin>>S[i];
    }
    for(int i=0;i<V;i++){
        cin>>T[i];
    }
    for(int i=0;i<V;i++){
        cin>>Y[i];
    }
    for(int i=0;i<V;i++){
        cin>>M[i];
    }

    vector<pair<int,pair<int,int>>> v[N+1];
    for(int i=0;i<V;i++){
        v[S[i]].push_back(make_pair(T[i],make_pair(Y[i],M[i])));
    }

    int dp[C+1][N+1];
    for(int i=0;i<C+1;i++){
        for(int j=0;j<N+1;j++){
            dp[i][j]=-1;
        }
    }

    queue<pair<int,int>> q;

    q.push(make_pair(C,1));
    dp[C][1]=0;
    while(!q.empty()){
        int c=q.front().first;
        int n=q.front().second;
        q.pop();
        for(int i=0;i<v[n].size();i++){
            int nn=v[n][i].first;
            int ny=v[n][i].second.first;
            int nm=v[n][i].second.second;
            int cc=dp[c][n]+nm;
            if(c-ny>=0&&(dp[c-ny][nn]==-1||dp[c-ny][nn]>cc)){
                dp[c-ny][nn]=cc;
                q.push(make_pair(c-ny,nn));
            }
        }
    }

    int mn=INT_MAX;
    for(int i=0;i<=C;i++){
        if(dp[i][N]!=-1) mn=min(mn,dp[i][N]);
    }

    if(mn==INT_MAX) cout<<"-1"<<endl;
    else cout<<mn<<endl;
}

DPテーブルを

dp[C+1][N+1];

と、コストと頂点で持ち、ダイクストラ用のキューも

queue<pair<int,int>>

と、コストと頂点で潜っていくようにしています。

コメント

タイトルとURLをコピーしました