This commit is contained in:
unlockable
2024-01-26 19:48:52 +01:00
parent 212e810db7
commit cc90db7d6d

View File

@@ -1,4 +1,27 @@
#include <stdio.h> #include <stdio.h>
#include <queue>
#include <functional>
struct Point {
unsigned short name;
int known_shortest;
int time;
Point(int _name, int _known_shortest, int _time): name(_name), known_shortest(_known_shortest), time(_time) {}
Point() {};
};
template <class T>
struct compare_point {
bool operator()(T &a, T &b) {
return a.known_shortest < b.known_shortest;
}
};
struct Edge{
unsigned short end, time, cost;
};
int N, M; int N, M;
unsigned short edges[1050000][3] = {0}; unsigned short edges[1050000][3] = {0};
// 边是否顺序? 按开始点排序 // 边是否顺序? 按开始点排序
@@ -8,6 +31,9 @@ unsigned short start = 0, terminal = 0;
int time_limit = 0; int time_limit = 0;
int path[1000] = {0}; int path[1000] = {0};
int current_cheap = 2147483647; int current_cheap = 2147483647;
Edge edges_dij[1050000] = {0};
bool included[66000] = {0};
Point points[66000];
int dfs(unsigned short cur, int cur_time, int cur_cost, int path_ptr) { int dfs(unsigned short cur, int cur_time, int cur_cost, int path_ptr) {
path[path_ptr] = cur; path[path_ptr] = cur;
@@ -37,34 +63,102 @@ int dfs(unsigned short cur, int cur_time, int cur_cost, int path_ptr) {
return 0; return 0;
} }
int dijkstra() {
std::priority_queue<Point, std::vector<Point>, compare_point<Point>> q;
for (int i = 0; i < N; i++) {
points[i] = Point{(unsigned short) i, 2147483647, 2147483647};
// q.push(points[i]);
}
// points[start].known_shortest = 0;
q.emplace(start, 0, 0);
while (!q.empty()) {
Point current = q.top();
q.pop();
if (current.name == terminal) {
printf("%d\n", current.known_shortest);
break;
}
for (int i = head[current.name]; i < head[current.name + 1]; i++) {
int new_time = current.time + edges_dij[i].time;
int new_cost = current.known_shortest + edges_dij[i].cost;
if (new_time > time_limit) {
continue;
}
if (new_cost < points[edges_dij[i].end].known_shortest) {
q.emplace(edges_dij[i].end, new_cost, new_time);
points[edges_dij[i].end].known_shortest = new_cost;
points[edges_dij[i].end].time = new_time < points[edges_dij[i].end].time ? new_time : points[edges_dij[i].end].time;
}
else if (new_time < points[edges_dij[i].end].time) {
q.emplace(edges_dij[i].end, new_cost, new_time);
points[edges_dij[i].end].time = new_time;
}
}
}
}
int main() { int main() {
scanf("%d %d", &N, &M); scanf("%d %d", &N, &M);
head[0] = 0; if (N < 50000) {
int next_empty_edge = 0; head[0] = 0;
int current_start = 0; int next_empty_edge = 0;
for (int i = 0; i < M; i++) { int current_start = 0;
int from, to, time, cost; for (int i = 0; i < M; i++) {
scanf("%d %d %d %d", &from, &to, &time, &cost); int from, to, time, cost;
if (from != current_start) { scanf("%d %d %d %d", &from, &to, &time, &cost);
for (int j = current_start + 1; j <= from; j++) { if (from != current_start) {
head[j] = next_empty_edge; for (int j = current_start + 1; j <= from; j++) {
head[j] = next_empty_edge;
}
current_start = from;
// head[from] = next_empty_edge;
} }
current_start = from; edges[next_empty_edge][0] = to;
// head[from] = next_empty_edge; edges[next_empty_edge][1] = time;
edges[next_empty_edge][2] = cost;
next_empty_edge++;
} }
edges[next_empty_edge][0] = to; head[++current_start] = next_empty_edge;
edges[next_empty_edge][1] = time; scanf("%hu %hu %d", &start, &terminal, &time_limit);
edges[next_empty_edge][2] = cost;
next_empty_edge++;
}
head[++current_start] = next_empty_edge;
scanf("%hu %hu %d", &start, &terminal, &time_limit);
dfs(start, 0, 0, 0); dfs(start, 0, 0, 0);
if (current_cheap == 2147483647) { if (current_cheap == 2147483647) {
printf("-1\n"); printf("-1\n");
return 0;
}
printf("%d\n", current_cheap);
return 0;
}
else {
head[0] = 0;
int next_empty_edge = 0;
int current_start = 0;
for (int i = 0; i < M; i++) {
unsigned short from, to, time, cost;
scanf("%hu %hu %hu %hu", &from, &to, &time, &cost);
if (from != current_start) {
for (int j = current_start + 1; j <= from; j++) {
head[j] = next_empty_edge;
}
current_start = from;
// head[from] = next_empty_edge;
}
// edges[next_empty_edge][0] = to;
// edges[next_empty_edge][1] = time;
// edges[next_empty_edge][2] = cost;
edges_dij[next_empty_edge] = Edge{to, time, cost};
next_empty_edge++;
}
head[++current_start] = next_empty_edge;
scanf("%hu %hu %d", &start, &terminal, &time_limit);
dijkstra();
return 0; return 0;
} }
printf("%d\n", current_cheap);
return 0;
} }