最短路径- URI在线判断1640
Shortest-Path - URI Online Judge 1640
我试图通过这个代码在uri在线判断,但我不知道我的错误在哪里,所有的测试我做的工作。
链接问题是这样的:https://www.urionlinejudge.com.br/repository/UOJ_1640_en.html
问题描述如下:
运输公司经常需要将货物从一个城市运送到另一个城市。这家运输公司与一家连锁酒店达成了一项特殊协议,允许其司机免费入住该连锁酒店。司机每天最多只能开车10个小时。运输公司想要找到一条从出发城市到目的地城市的路线,使得司机总是可以在连锁酒店中的一家酒店过夜,并且从一家酒店到下一家酒店(或目的地)最多需要开车10个小时。当然,交货所需的天数也应该尽量减少。输入
输入文件包含几个测试用例。每个测试用例以包含整数n(2≤n≤10000)的行开头,n是规划路由时需要考虑的城市数目。为简单起见,城市编号从1到n,其中1是起始城市,n是目的地城市。下一行包含一个整数h,后面跟着数字c1, c2,…, ch表示该连锁酒店所在城市的数量。可以假设0≤h≤min(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。
和我的尝试解决方案是在我的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<<"-1n";
}
else{
cout<<total<<endl;
}
}
return 0;
}
感谢您的帮助
这个问题可以通过首先计算酒店之间的最小旅行时间来简化。这意味着你从每个酒店计算,通过道路到达其他酒店所需的最短时间。
然后,计算城市1
到每家酒店的最短距离,同理,计算城市n
到每家酒店的最短距离。
使用新的距离,用酒店和其他2个城市之间的最短路径形成一个新的图。如果路径长度为>600
,则忽略它(这意味着不要将其放入新图中)。然后使用Dijkstra,每条边的权重为1
。这将告诉你到达目的地所需的最少酒店数量+ 1。如果新图中没有路径,则不可能。
算法将取O((k+2)m log n + m log (k+2)) = O(km log n)
- 如何判断SSL_read是否已经接收并处理了来自单个消息的所有记录
- 如何判断类型双关语在我的平台上是否可以?
- 失败,出现错误 87:参数不正确.如何判断哪个参数不正确?
- 如何判断是否在编译时计算了"constexpr"(无需手动检查)
- 如何构造一个类型特征,可以判断一个类型的私有方法是否可以在另一个类型的构造函数中调用?
- 如何判断指针是否是指向数组的指针
- C++如何判断互斥体在阻塞其他线程时是否被单个线程不成比例地占用
- 如何判断 c++ 向量中的值类型(整数或双精度)?
- 通过 pid 窗口判断进程是否存在
- 如何判断我正在运行的Microsoft C++代码是否使用 /EHa 开关编译?
- 如何判断是否有另一个线程试图保持互斥锁?
- 编写一个函数,该函数将通过判断其每个参数的类型来自动确定其返回值
- 如何通过其手柄判断堆是否序列化
- 如何判断我的过程中的哪个模块创建了哪个堆
- 如何判断从 CreateProcess 启动的进程是否仍在运行
- boost::P rogram_options 一种判断值是从命令行还是 ini 文件的方法?
- 如果有办法判断编译器是否真的内联C++函数
- 如何判断虚拟内存页是否已锁定
- 如何判断类型是否是特定模板类的实例
- 最短路径- URI在线判断1640