2016-09-01 2 views
-1

私はuriオンラインジャッジでこのコードを渡そうとしていましたが、私はどこにエラーがあるのか​​分かりません。最短パス - URIオンラインジャッジ1640

リンクの問題はこれです: https://www.urionlinejudge.com.br/repository/UOJ_1640_en.html

問題の説明は次のとおりです。

運送会社は、多くの場合、別の都市に1つの都市から商品をお届けする必要があります。運送会社はホテルチェーンに特別な契約を結び、運転手がこのチェーンのホテルに無料で滞在できるようにしています。運転手は1日に最大10時間運転することができます。運送会社は出発都市から目的地までのルートを探しています。そのため、運転手はホテルチェーンのホテルの1つでいつも夜を過ごすことができ、ホテルからホテルまで10時間以内に運転する必要があります次のホテル(または目的地)。もちろん、商品の配送に必要な日数も最小限に抑える必要があります。 入力

入力ファイルにはいくつかのテストケースが含まれています。各テストケースは、ルートを計画する際に考慮する都市の数である整数n(2≦n≦10000)を含む行から始まります。簡単にするために、都市は1からnまで番号が付けられています。ここで1は開始都市で、nは目的地の都市です。次の行には、ホテルチェーンのホテルが位置する都市の番号を示す番号c1、c2、...、chが続く整数hが含まれています。 0≤h≤min(n、100)と仮定できます。各テストケースの3行目には、経路を計画するために考慮される道路の数m(1≦m≦105)の整数が含まれています。次のm行は道路を表しています。各道路は、3つの整数a、b、t(1≦a、b≦nおよび1≦t≦600)を含む線で記述され、a、bは道路によって接続された2つの都市であり、tは運転手が道路の一端から他端まで運転するのに必要な時間。入力はn = 0で終了します。 出力

各テストケースについて、輸送会社が都市1から都市nへの配達のために予約しなければならない最低限のホテル数を含む1行を印刷します。運転手が1日に最大10時間運転するようなルートを見つけることができない場合は、代わりに-1を印刷します。

と私のトライソリューションは、私のgithubの上にある:任意の助け https://github.com/h31nr1ch/uri/blob/master/1640.cpp

#include <iostream> 
#include <vector> 
#include <string> 
#include <list> 
#include <limits> // for numeric_limits 
#include <set> 
#include <utility> // for pair 
#include <algorithm> 
#include <iterator> 
using namespace std; 

typedef long long int vertex_t; 
typedef double weight_t; 
const weight_t max_weight = numeric_limits<double>::infinity(); 

struct neighbor { 
    vertex_t target; 
    weight_t weight; 
    weight_t current; 
    bool hotel; 
    neighbor(vertex_t arg_target, weight_t arg_weight,weight_t arg_current,bool arg_hotel):target(arg_target), weight(arg_weight),current(arg_current),hotel(arg_hotel){ } 
}; 

typedef vector<vector<neighbor> > adjacency_list_t; 

void DijkstraComputePaths(vertex_t source,adjacency_list_t &adjacency_list, vector<weight_t> &min_distance, vector<vertex_t> &previous,vector<vertex_t> &hoteis,vector<vertex_t> &weights,vector<bool> &tHotel){ 
    int n = adjacency_list.size(); 
    min_distance.clear(); 
    min_distance.resize(n, max_weight); 
    min_distance[source] = 0; 
    previous.clear(); 
    previous.resize(n, -1); 
    weights.clear(); 
    weights.resize(n,0); 
    tHotel.clear(); 
    tHotel.resize(n,false); 
    set<pair<weight_t, vertex_t> > vertex_queue; 
    vertex_queue.insert(make_pair(min_distance[source], source)); 
    while (!vertex_queue.empty()){ 
    weight_t dist = vertex_queue.begin()->first; 
    vertex_t u = vertex_queue.begin()->second; 
    vertex_queue.erase(vertex_queue.begin()); 
    vector<neighbor> &neighbors = adjacency_list[u]; 
    for (vector<neighbor>::iterator neighbor_iter = neighbors.begin(); neighbor_iter != neighbors.end(); neighbor_iter++){ 
     vertex_t v = neighbor_iter->target; 
     weight_t weight = neighbor_iter->weight; 
     weight_t current= neighbor_iter->current; 
     weight_t distance_through_u = dist + weight; 
     if (distance_through_u < min_distance[v]) { 
     bool l=true; 
     bool ho=false;//Variavel criada para falar se dormiu no hotel ou nao 
     //if(distance_through_u>600){ 
     if(weight+weights[u]>600){ 
      //Procurando por um hotel 
      if(hoteis.size()==0) 
      l=false; 
      for(vector<vertex_t>::iterator it=hoteis.begin();it!=hoteis.end();it++){ 
      if(*it==u){ 
       l=true; 
       ho=true; 
       break; 
      } 
      else{ 
       l=false; 
      } 
      } 
     } 
     if(l){ 
      if(ho){ 
      tHotel[v]=true; 
      weights[v]=weight; 
      //cout<<"O nó u= "<<u<<" e nó v= "<<v<<" precisaram de hotel! Entao o peso é: "<<weights[v]<<endl; 
      } 
      else{ 
      tHotel[v]=false; 
      weights[v]=distance_through_u; 
      //cout<<"O nó u= "<<u<<" e nó v= "<<v<<" NÃO precisaram de hotel! Entao o peso é: "<<weights[v]<<endl; 
      } 
      vertex_queue.erase(make_pair(min_distance[v], v)); 
      min_distance[v] = distance_through_u; 
      previous[v] = u; 
      vertex_queue.insert(make_pair(min_distance[v], v)); 
     } 
     } 
    } 
    } 
} 

list<vertex_t> DijkstraGetShortestPathTo(vertex_t vertex, const vector<vertex_t> &previous){ 
    list<vertex_t> path; 
    for (;vertex != -1; vertex = previous[vertex]) 
    path.push_front(vertex); 
    return path; 
} 

int main(){ 
    int n=1,m,x,y,w,v; 
    while(n!=0){ 
    vector<vertex_t> hoteis; 
    cin>>n; 
    adjacency_list_t adjacency_list(n); 
    if(n==0) 
     break; 
    cin>>v; 
    for(int i=0;i<v;i++){ 
     cin>>x; 
     hoteis.push_back(x-1); 
    } 
    cin>>m; 
    for(int i=0;i<m;i++){ 
     cin>>x>>y>>w; 
     adjacency_list[x-1].push_back(neighbor(y-1,w,0,false)); 
    } 
    vector<weight_t> min_distance; 
    vector<vertex_t> previous; 
    vector<vertex_t> weights; 
    vector<bool> tHotel; 
    DijkstraComputePaths(0, adjacency_list, min_distance, previous,hoteis,weights,tHotel); 
    //cout << "Distance from 0 to "<<n-1<<" : " << min_distance[n-1] << endl; 
    list<vertex_t> path = DijkstraGetShortestPathTo(n-1, previous); 
    //cout<<"Weights: "; 
    //copy(min_distance.begin(),min_distance.end(),ostream_iterator<vertex_t>(cout," ")); 
    //cout<<endl; 
    //cout << "Path : "; 
    //copy(path.begin(), path.end(), ostream_iterator<vertex_t>(cout, " ")); 
    //cout<<endl; 
    int total=0; 
    //for(vector<bool>::iterator it=tHotel.begin();it!=tHotel.end();it++){ 
    // cout<<*it<<" "; 
    //} 
    for(list<vertex_t>::iterator it=path.begin();it!=path.end();it++){ 
     if(tHotel[*it]==1) 
     total++; 
    } 
    //cout<<endl; 
    if(min_distance[n-1]==max_weight){ 
     cout<<"-1\n"; 
    } 
    else{ 
     cout<<total<<endl; 
    } 
    } 
    return 0; 
} 

感謝。

答えて

1

問題は、まずホテル間の最小移動時間を計算することで簡素化できます。つまり、道路を経由して他のすべてのホテルにアクセスするのにかかる最短時間は、各ホテルから計算されます。

都市nと同様に、都市1からホテルまでの最短距離を計算します。

新しい距離を使用して、ホテルと他の2都市との最短経路を使用して新しいグラフを作成します。パスの長さが>600の場合、無視します(つまり、新しいグラフに入れない)。その後、ダイクストラを使用して、各エッジのウェイトを1にします。これにより、目的地に到達するために必要な最低限のホテル数が+1になります。新しいグラフにパスがない場合は不可能です。

アルゴリズムは、O((k+2)m log n + m log (k+2)) = O(km log n)

関連する問題