完全披露:这是一个在线课程。
代码使用Bellman-Ford算法计算图表中起始节点与所有其他节点之间的距离。图形可能包含负循环:在这种情况下,输出应使用“ - ”表示该距离。如果起始节点和另一个节点之间没有链接,它应该是'*'。否则,它应该输出距离。
代码正在运行,但我相信存在溢出问题,我不知道如何解决。约束指定以下最大值:
测试所有与逻辑相关的极端情况导致没有问题,一切正常。失败的测试(很可能)与溢出有关。
代码
void bfs(vector<vector<int> > &adj, queue<int> q, vector<bool> &shortest) {
int size = adj.size();
vector<bool> visited(size, false);
while (!q.empty()) {
int v = q.front();
if (visited[v]) {
q.pop();
} else {
q.pop();
for (int i = 0; i < adj[v].size(); i++) {
shortest[adj[v][i]] = true;
q.push(adj[v][i]);
}
}
visited[v] = true;
}
}
void shortest_paths(vector<vector<int> > &adj, vector<vector<int> > &cost, int s,
vector<double> &distance, vector<bool> &reachable, vector<bool> &shortest) {
int size = adj.size();
distance[s] = 0;
reachable[s] = true;
queue<int> negative_cycle;
// Set initial distances and get negative cycles
for (int i = 0; i <= size; i++) {
for (int j = 0; j < size; j++) {
for (int k = 0; k < adj[j].size(); k++) {
// Edge relaxation
if (distance[adj[j][k]] > distance[j] + cost[j][k]) {
reachable[adj[j][k]] = true;
if (i == size) {
// Store negative cycles
negative_cycle.push(adj[j][k]);
shortest[adj[j][k]] = true;
}
distance[adj[j][k]] = distance[j] + cost[j][k];
}
}
}
}
bfs(adj, negative_cycle, shortest);
}
和主
int main() {
int n, m, s;
std::cin >> n >> m;
vector<vector<int> > adj(n, vector<int>());
vector<vector<int> > cost(n, vector<int>());
for (int i = 0; i < m; i++) {
double x, y, w;
std::cin >> x >> y >> w;
adj[x - 1].push_back(y - 1);
cost[x - 1].push_back(w);
}
std::cin >> s;
s--;
vector<double> distance(n, std::numeric_limits<double>::infinity());
vector<bool> reachable(n, false);
vector<bool> shortest(n, false);
shortest_paths(adj, cost, s, distance, reachable, shortest);
for (int i = 0; i < n; i++) {
if (!reachable[i]) {
std::cout << "*\n";
} else if (shortest[i]) {
std::cout << "-\n";
} else {
std::cout << distance[i] << "\n";
}
}
}
我正在使用double和infinity,因为算法需要它(你可以阅读它here)。从我已经完成的谷歌搜索,我得到这不应该溢出,因为最大可能的距离将是10 ^ 4 * 10 ^ 9 = 10 ^ 13,这仍然是在双倍的跨度内。我没有太多经验使用这样的无限或双打,从我研究过的内容我无法追踪问题。
是否有使用双无穷大的替代方法(因为long long
没有它并且它的max_size不能在问题的上下文中使用)?在这种情况下是否会出现双重溢出或其他相关问题(比较失败等)?