C++ 最短路径-URI在线判断1640

C++ 最短路径-URI在线判断1640,c++,graph,dijkstra,shortest-path,C++,Graph,Dijkstra,Shortest Path,我试图在uri online judge中传递这段代码,但我不知道我的错误在哪里,我所做的所有测试都正常工作 链接问题是: 问题描述如下: 运输公司通常需要将货物从一个城市运送到另一个城市。该运输公司与一家连锁酒店达成了一项特殊协议,允许其司机免费入住该连锁酒店。司机每天最多只能开车10小时。交通公司希望找到一条从出发城市到目的城市的路线,这样司机就可以在连锁酒店的其中一家酒店过夜,并且从一家酒店到下一家酒店(或目的地)最多需要10个小时。当然,交付货物所需的天数也应尽量减少。 输入 输入文件

我试图在uri online judge中传递这段代码,但我不知道我的错误在哪里,我所做的所有测试都正常工作

链接问题是:

问题描述如下:

运输公司通常需要将货物从一个城市运送到另一个城市。该运输公司与一家连锁酒店达成了一项特殊协议,允许其司机免费入住该连锁酒店。司机每天最多只能开车10小时。交通公司希望找到一条从出发城市到目的城市的路线,这样司机就可以在连锁酒店的其中一家酒店过夜,并且从一家酒店到下一家酒店(或目的地)最多需要10个小时。当然,交付货物所需的天数也应尽量减少。 输入

输入文件包含几个测试用例。每个测试用例从一行开始,该行包含一个整数n,(2≤ N≤ 10000),规划路线时要考虑的城市数量。为简单起见,城市编号从1到n,其中1是起始城市,n是目的地城市。下一行包含一个整数h,后跟数字c1、c2、…、ch,表示连锁酒店所在城市的编号。您可以假设0≤ H≤ 最小值(n,100)。每个测试用例的第三行包含一个整数m(1≤ M≤ 105),规划路线时要考虑的道路数量。以下m线描述了道路。每条道路由一条包含3个整数a、b、t(1)的线描述≤ a、 b≤ n和1≤ T≤ 600),其中a、b是道路连接的两个城市,t是驾驶员从道路一端行驶到另一端所需的时间(以分钟为单位)。输入以n=0终止。 输出

对于每个测试用例,打印一行,其中包含运输公司必须预订的从1号城市到n号城市的最少酒店数量。如果无法找到驾驶员每天最多只能行驶10小时的路线,请打印-1

我的try解决方案位于我的github上:

#包括
#包括
#包括
#包括
#包括//用于数字限制
#包括
#包括//对
#包括
#包括
使用名称空间std;
typedef long long int vertex_t;
typedef双倍重量;
常量重量最大重量=数值限制::无穷大();
结构邻居{
顶点目标;
重量;
重量/电流;
布尔酒店;
邻居(顶点目标、重量、重量当前、布尔酒店):目标(重量目标)、重量(重量当前)、酒店(重量酒店){}
};
typedef向量邻接列表;
void DijkstraComputePaths(顶点源、邻接列表和邻接列表、向量和最小距离、向量和上一个、向量和hoteis、向量和权重、向量和tHotel){
int n=邻接列表.size();
最小距离。清除();
最小距离。调整大小(n,最大重量);
最小距离[源]=0;
previous.clear();
上一个。调整大小(n,-1);
重量。清除();
权重。调整大小(n,0);
tHotel.clear();
tHotel.resize(n,false);
设置顶点队列;
顶点_队列。插入(生成_对(最小_距离[源],源));
而(!vertex_queue.empty()){
weight\u t dist=vertex\u queue.begin()->first;
vertex\u t u=vertex\u队列。begin()->秒;
vertex_queue.erase(vertex_queue.begin());
向量和邻域=邻接列表[u];
for(vector::iterator neighbor_iter=neighbors.begin();neighbor_iter!=neighbors.end();neighbor_iter++){
顶点=相邻节点->目标;
重量=邻居的重量->重量;
重量\u t电流=邻居\u iter->电流;
重量-距离-距离=距离+重量;
if(从距离到最小距离[v]){
布尔=真;
bool ho=false;//Variavel criada para falar se dormiu no酒店
//如果(距离_到_>600){
如果(重量+重量[u]>600){
//普罗坎多波鲁姆酒店
如果(hoteis.size()==0)
l=假;
for(vector::iterator it=hoteis.begin();it!=hoteis.end();it++){
如果(*it==u){
l=真;
ho=正确;
打破
}
否则{
l=假;
}
}
}
如果(l){
if(ho){
tHotel[v]=真;
重量[v]=重量;

//cout问题可以通过首先计算酒店之间的最小旅行时间来简化。这意味着您可以计算从每个酒店出发,通过道路到达其他酒店所需的最小时间

然后,计算从城市
1
到每个酒店的最短距离,城市
n
也是如此

使用新的距离,使用酒店与其他2个城市之间的最短路径形成一个新的图表。如果路径长度为
>600
,则忽略它(这意味着不要将其放入新图表中)。然后使用Dijkstra,每条边的权重为
1
。这将为您提供到达目的地+1所需的最少酒店数量。如果新图表中没有路径,则不可能


该算法将取O((k+2)m log n+m log(k+2))=O(km log n)

这个问题可以通过首先计算酒店之间的最小旅行时间来简化。这意味着您可以计算从每个酒店经过道路到达其他酒店所需的最小时间

然后,计算从城市
1
到每个酒店的最短距离,城市
n
也是如此

使用新的距离,使用酒店与其他2个城市之间的最短路径形成一个新的图表。如果路径长度为
>600
,则忽略它(这意味着不要将其放入新图表中)。然后使用Dijkstra,每条边的权重为
1
。这将为您提供到达目的地+1所需的最少酒店数量。如果新图表中没有路径,则
#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;
}