【发布时间】:2022-01-20 13:35:37
【问题描述】:
我有一个加权无向图。它的顶点是两个集合的一部分 - S 和 T。首先,输入边。然后指定哪些顶点是 T 集的一部分(其余顶点是 S 集的一部分)。然后是 q 个查询。对于每个查询(由一个源顶点组成),程序必须打印指定的源顶点和集合 T 的任何顶点之间的最短路径。
我使用 Dijkstra 算法实现了该程序。我为源顶点上的每个查询调用它(dijkstra 返回源顶点与所有其他顶点之间的距离),然后返回这些数字中的最小值。
const int M = 1000000;
std::unordered_set<int> T;
class Node {
public:
int endVertex; // stores the second vertex of the edge
int weight; // stores the weight required, it is the weight of the edge
Node(int end, int weight) {
this->endVertex = end;
this->weight = weight;
}
};
struct NodeComparator {
bool operator()(const Node &first, const Node &second) {
return first.weight > second.weight;
}
};
class Graph {
private:
std::unordered_map<int, std::vector<Node>> adjacencyList; // it's a vector because there may be repeated Nodes
int numberOfVertices;
std::vector<int> dijkstra(int source) {
std::priority_queue<Node, std::vector<Node>, NodeComparator> heap;
std::vector<int> distances(this->numberOfVertices, M);
std::unordered_set<int> visited;
// distance source->source is 0
distances[source] = 0;
heap.emplace(source, 0);
while (!heap.empty()) {
int vertex = heap.top().endVertex;
heap.pop();
// to avoid repetition
if (visited.find(vertex) != visited.end()) {
continue;
}
for (Node node: adjacencyList[vertex]) {
// relaxation
if (distances[node.endVertex] > distances[vertex] + node.weight) {
distances[node.endVertex] = distances[vertex] + node.weight;
heap.emplace(node.endVertex, distances[node.endVertex]);
}
}
// mark as visited to avoid going through the same vertex again
visited.insert(vertex);
}
return distances;
}
int answer(int source) {
std::vector<int> distances = this->dijkstra(source);
std::set<int> answer;
for (int i: T) {
answer.insert(distances[i]);
}
return *answer.begin();
}
// other methods
};
// main()
但是,由于超时,我的解决方案没有通过一半的测试。我用 Floyd-Warshall 算法替换了我的 dijkstra 方法,该算法直接覆盖了起始邻接矩阵,因为我认为该方法只会被调用一次,然后每个查询只会在矩阵的源行中找到最小元素。这次超时更严重。
是否有针对最短路径高效查询的特定算法?如何改进我的算法?
【问题讨论】:
-
顺便说一下,将
std::ios::sync_with_stdio(false); cin.tie(NULL);添加到 main 不会以任何方式加速我的程序。 -
你看到下面我的cmets了吗?你检查了吗?
-
@aropan 是的,我做到了。我上传了你的答案。然而,这不是解决方案。我现在正在添加它。
标签: c++ algorithm graph shortest-path dijkstra