-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path10816-Travelinthedesert.cpp
executable file
·146 lines (123 loc) · 2.95 KB
/
10816-Travelinthedesert.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//
// 10816 - Travel in the desert.cpp
// Uva
//
// Created by Alexander Faxå on 2012-02-19.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <stdio.h>
#define MAX_VERTICES 101
#define INF 1e10
#define EPS 1e-5
using namespace std;
struct vertex;
struct edge {
vertex* to;
double temp;
double weight;
};
struct vertex
{
int index;
vector<edge> out;
double temp, weight; // Current cost
vertex* prev; // Back tracing
};
vertex v[MAX_VERTICES];
int numv, nume, s, t;
typedef pair<double, vertex*> elem;
bool ShortestPath(double maxTemp, bool first)
{
vertex* source = &v[s];
vertex* dest = &v[t];
for(int i = 0; i < numv; ++i)
{
v[i].index = i;
if(first)
v[i].temp = INF;
else
v[i].weight = INF;
v[i].prev = 0; // 0 at end if not on the path to dest
}
source->weight = 0.0;
source->temp = 0.0;
priority_queue<elem, vector<elem>, greater<elem> > pq;
pq.push(elem(0.0, source));
while(!pq.empty())
{
elem ce = pq.top();
vertex* cur = ce.second;
pq.pop();
if((first && (ce.first - cur->temp > EPS || ce.first - cur->temp < -EPS) ) || (!first && (ce.first - cur->weight > EPS || ce.first - cur->weight < -EPS)))
continue; // Already processed
if(cur == dest)
return true;
for(vector<edge>::iterator it = cur->out.begin();
it != cur->out.end(); ++it) // Go through the edges
{
double newCost;
if(first)
newCost = max(cur->temp, it->temp);
else
{
newCost = cur->weight + it->weight;
if(it->temp > maxTemp)
newCost = INF;
}
if((first && newCost < it->to->temp) || (!first && newCost < it->to->weight))
{
if(first)
it->to->temp = newCost;
else
it->to->weight = newCost;
it->to->prev = cur;
pq.push(elem(newCost, it->to));
}
}
}
return false; // No way to reach the end
}
void print_road(int cur)
{
if(cur == s)
{
printf("%d", s+1);
return ;
}
print_road(v[cur].prev->index);
printf(" %d", cur+1);
}
int main()
{
while(cin >> numv >> nume)
{
for (int i = 0; i < MAX_VERTICES; i++) {
v[i].out.clear();
v[i].prev = 0;
}
cin >> s >> t;
s--; t--;
edge e;
for (int i = 0; i < nume; i++) {
int x, y;
double r, d;
cin >> x >> y >> r >> d;
x--; y--;
e.weight = d;
e.temp = r;
e.to = &v[y];
v[x].out.push_back(e);
e.to = &v[x];
v[y].out.push_back(e);
}
ShortestPath(-1, true);
ShortestPath(v[t].temp, false);
print_road(t);
printf("\n%0.1lf %0.1lf\n", v[t].weight, v[t].temp);
}
return 0;
}