从集合删除元素时运行时错误

发布于 2025-01-28 04:15:59 字数 6436 浏览 2 评论 0原文

我找不到我的代码出了问题。当我将其上传到测试系统时,即使在我尝试使用时可以正常工作,它也会说“运行时错误”。将我的代码部分放在其中之后,我认为问题存在:

void Erase(std::set<std::pair<int64_t , int64_t>> &queue, const std::vector<int64_t>& paths, int64_t now) {
    std::pair<int64_t , int64_t> target = {paths[now], now};
    queue.erase(queue.find(target));
}

void Relaxation(int64_t v, int64_t now, std::vector<std::vector<int64_t>>& matrix, std::vector<bool>& was, std::vector<std::vector<int64_t>>& edges, std::set<std::pair<int64_t, int64_t>>& queue, std::vector<int64_t>& paths) {
    Erase(queue, paths, now);
    was[now] = true;
    for (const auto& neigh : edges[now]) {
        if (paths[neigh] > matrix[neigh][now] && !was[neigh]) { // If delete this if code works
            Erase(queue, paths, neigh);
            paths[neigh] = matrix[neigh][now];
            queue.insert({matrix[neigh][now], neigh});
        }
    }
}

这是整个代码:

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <cmath>

void dfs(std::vector<std::vector<bool>>& matrix, int64_t v, bool* was_here, int64_t now, int64_t count, std::vector<int64_t>& vertices) {
    was_here[now] = true;
    vertices[now] = count;
    for (int i = 1; i < v + 1; ++i) {
        if (matrix[now][i] && !was_here[i]) {
            dfs(matrix, v, was_here, i, count, vertices);
        }
    }
}

std::pair<int64_t, std::vector<int64_t>> Components(std::vector<std::vector<bool>>& matrix, int64_t v) {
    bool was_here[v + 1];
    std::vector<int64_t> vertices(v + 1);
    int64_t count = 1;
    for (int64_t i = 1; i < v + 1; ++i) {
        if (!was_here[i]) {
            dfs(matrix, v, was_here, i, count, vertices);
            ++count;
        }
    }
    --count;
    return {count, vertices};
}

void Erase(std::set<std::pair<int64_t , int64_t>> &queue, const std::vector<int64_t>& paths, int64_t now) {
    std::pair<int64_t , int64_t> target = {paths[now], now};
    queue.erase(queue.find(target));
}

void Relaxation(int64_t v, int64_t now, std::vector<std::vector<int64_t>>& matrix, std::vector<bool>& was, std::vector<std::vector<int64_t>>& edges, std::set<std::pair<int64_t, int64_t>>& queue, std::vector<int64_t>& paths) {
    Erase(queue, paths, now);
    was[now] = true;
    for (const auto& neigh : edges[now]) {
        if (paths[neigh] > matrix[neigh][now] && !was[neigh]) {
            Erase(queue, paths, neigh);
            paths[neigh] = matrix[neigh][now];
            queue.insert({matrix[neigh][now], neigh});
        }
    }
}

std::vector<int64_t> Prim(int64_t v, std::vector<std::vector<int64_t>>& matrix, std::vector<std::vector<int64_t>>& edges) {
    std::set<std::pair<int64_t, int64_t>> queue;
    std::vector<int64_t> paths(v + 1);
    std::vector<bool> was(v + 1, false);
    paths[1] = 0;
    queue.insert({0, 1});
    const int64_t upper_bound = 1000000000;
    for (int i = 2; i < v + 1; ++i) {
        queue.insert({upper_bound, i});
        paths[i] = upper_bound;
    }
    while (!queue.empty()) {
        int64_t now = queue.begin()->second;
        Relaxation(v, now, matrix, was, edges, queue, paths);
    }
    return paths;
}

double SolutionB6(int64_t v, std::vector<std::vector<int64_t>>& matrix, std::vector<std::vector<int64_t>>& edges) {
    std::vector<int64_t> tree = Prim(v, matrix, edges);
    int64_t res = 0;
    for (int64_t i = 1; i < v + 1; ++i) {
        res += tree[i];
    }
    const double accuracy = 1000000;
    double true_res = double(res) / accuracy;
    return true_res;
}

int main() {
    int64_t v, e;
    std::cin >> v;
    std::vector<std::vector<int64_t>> vertices(v + 1, std::vector<int64_t>(2, 0));
    for (int i = 1; i < v + 1; ++i) {
        int64_t x, y;
        std::cin >> x >> y;
        vertices[i][0] = x;
        vertices[i][1] = y;
    }
    std::cin >> e;
    std::vector<std::vector<bool>> matrix(v + 1, std::vector<bool>(v + 1, false));
    std::vector<std::vector<int64_t>> edges;
    for (int64_t i = 0; i < e; ++i) {
        int64_t v1, v2;
        std::cin >> v1 >> v2;
        matrix[v1][v2] = true;
        matrix[v2][v1] = true;
        edges.push_back({v1, v2});
    }
    auto pair = Components(matrix, v);
    auto amount = pair.first;
    auto info = pair.second;
    std::vector<std::vector<int64_t>> matrix_new(amount + 1, std::vector<int64_t>(amount + 1, 0));
    std::vector<int64_t> sample;
    std::vector<std::vector<int64_t>> edges_new(amount + 1);
    const int64_t accuracy = 1000000;
    for (int64_t i = 1; i < amount + 1; ++i) {
        for (int64_t j = 1; j < amount + 1; ++j) {
            if (j != i) {
                edges_new[i].push_back(j);
            }
        }
    }
    for (int64_t i = 1; i < v + 1; ++i) {
        for (int64_t j = i + 1; j < v + 1; ++j) {
            std::vector<int64_t> v1 = vertices[i];
            int64_t x1 = v1[0];
            int64_t y1 = v1[1];
            std::vector<int64_t> v2 = vertices[j];
            int64_t x2 = v2[0];
            int64_t y2 = v2[1];
            int64_t c1 = info[i];
            int64_t c2 = info[j];
            int64_t x = x1 - x2;
            int64_t y = y1 - y2;
            double weight = std::sqrt(x * x + y * y);
            double was = double(matrix_new[c1][c2]) / double(accuracy);
            if (was == 0) {
                matrix_new[c1][c2] = weight * accuracy;
                matrix_new[c2][c1] = weight * accuracy;
            } else {
                matrix_new[c1][c2] = std::min(weight, was);
                matrix_new[c2][c1] = matrix_new[c1][c2];
            }
        }
    }
    std::cout << SolutionB6(amount, matrix_new, edges_new);
    return 0;
}

测试系统使用GNU C ++ 20 10.2,此测试中的运行时错误:

1
1 1
0

I can't find what is wrong with my code. When I upload it to my testing system, it says "Runtime error", even though it works fine when I try in CLion. After putting there my code part by part, I figured that problem is with this:

void Erase(std::set<std::pair<int64_t , int64_t>> &queue, const std::vector<int64_t>& paths, int64_t now) {
    std::pair<int64_t , int64_t> target = {paths[now], now};
    queue.erase(queue.find(target));
}

void Relaxation(int64_t v, int64_t now, std::vector<std::vector<int64_t>>& matrix, std::vector<bool>& was, std::vector<std::vector<int64_t>>& edges, std::set<std::pair<int64_t, int64_t>>& queue, std::vector<int64_t>& paths) {
    Erase(queue, paths, now);
    was[now] = true;
    for (const auto& neigh : edges[now]) {
        if (paths[neigh] > matrix[neigh][now] && !was[neigh]) { // If delete this if code works
            Erase(queue, paths, neigh);
            paths[neigh] = matrix[neigh][now];
            queue.insert({matrix[neigh][now], neigh});
        }
    }
}

Here is the whole code:

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <cmath>

void dfs(std::vector<std::vector<bool>>& matrix, int64_t v, bool* was_here, int64_t now, int64_t count, std::vector<int64_t>& vertices) {
    was_here[now] = true;
    vertices[now] = count;
    for (int i = 1; i < v + 1; ++i) {
        if (matrix[now][i] && !was_here[i]) {
            dfs(matrix, v, was_here, i, count, vertices);
        }
    }
}

std::pair<int64_t, std::vector<int64_t>> Components(std::vector<std::vector<bool>>& matrix, int64_t v) {
    bool was_here[v + 1];
    std::vector<int64_t> vertices(v + 1);
    int64_t count = 1;
    for (int64_t i = 1; i < v + 1; ++i) {
        if (!was_here[i]) {
            dfs(matrix, v, was_here, i, count, vertices);
            ++count;
        }
    }
    --count;
    return {count, vertices};
}

void Erase(std::set<std::pair<int64_t , int64_t>> &queue, const std::vector<int64_t>& paths, int64_t now) {
    std::pair<int64_t , int64_t> target = {paths[now], now};
    queue.erase(queue.find(target));
}

void Relaxation(int64_t v, int64_t now, std::vector<std::vector<int64_t>>& matrix, std::vector<bool>& was, std::vector<std::vector<int64_t>>& edges, std::set<std::pair<int64_t, int64_t>>& queue, std::vector<int64_t>& paths) {
    Erase(queue, paths, now);
    was[now] = true;
    for (const auto& neigh : edges[now]) {
        if (paths[neigh] > matrix[neigh][now] && !was[neigh]) {
            Erase(queue, paths, neigh);
            paths[neigh] = matrix[neigh][now];
            queue.insert({matrix[neigh][now], neigh});
        }
    }
}

std::vector<int64_t> Prim(int64_t v, std::vector<std::vector<int64_t>>& matrix, std::vector<std::vector<int64_t>>& edges) {
    std::set<std::pair<int64_t, int64_t>> queue;
    std::vector<int64_t> paths(v + 1);
    std::vector<bool> was(v + 1, false);
    paths[1] = 0;
    queue.insert({0, 1});
    const int64_t upper_bound = 1000000000;
    for (int i = 2; i < v + 1; ++i) {
        queue.insert({upper_bound, i});
        paths[i] = upper_bound;
    }
    while (!queue.empty()) {
        int64_t now = queue.begin()->second;
        Relaxation(v, now, matrix, was, edges, queue, paths);
    }
    return paths;
}

double SolutionB6(int64_t v, std::vector<std::vector<int64_t>>& matrix, std::vector<std::vector<int64_t>>& edges) {
    std::vector<int64_t> tree = Prim(v, matrix, edges);
    int64_t res = 0;
    for (int64_t i = 1; i < v + 1; ++i) {
        res += tree[i];
    }
    const double accuracy = 1000000;
    double true_res = double(res) / accuracy;
    return true_res;
}

int main() {
    int64_t v, e;
    std::cin >> v;
    std::vector<std::vector<int64_t>> vertices(v + 1, std::vector<int64_t>(2, 0));
    for (int i = 1; i < v + 1; ++i) {
        int64_t x, y;
        std::cin >> x >> y;
        vertices[i][0] = x;
        vertices[i][1] = y;
    }
    std::cin >> e;
    std::vector<std::vector<bool>> matrix(v + 1, std::vector<bool>(v + 1, false));
    std::vector<std::vector<int64_t>> edges;
    for (int64_t i = 0; i < e; ++i) {
        int64_t v1, v2;
        std::cin >> v1 >> v2;
        matrix[v1][v2] = true;
        matrix[v2][v1] = true;
        edges.push_back({v1, v2});
    }
    auto pair = Components(matrix, v);
    auto amount = pair.first;
    auto info = pair.second;
    std::vector<std::vector<int64_t>> matrix_new(amount + 1, std::vector<int64_t>(amount + 1, 0));
    std::vector<int64_t> sample;
    std::vector<std::vector<int64_t>> edges_new(amount + 1);
    const int64_t accuracy = 1000000;
    for (int64_t i = 1; i < amount + 1; ++i) {
        for (int64_t j = 1; j < amount + 1; ++j) {
            if (j != i) {
                edges_new[i].push_back(j);
            }
        }
    }
    for (int64_t i = 1; i < v + 1; ++i) {
        for (int64_t j = i + 1; j < v + 1; ++j) {
            std::vector<int64_t> v1 = vertices[i];
            int64_t x1 = v1[0];
            int64_t y1 = v1[1];
            std::vector<int64_t> v2 = vertices[j];
            int64_t x2 = v2[0];
            int64_t y2 = v2[1];
            int64_t c1 = info[i];
            int64_t c2 = info[j];
            int64_t x = x1 - x2;
            int64_t y = y1 - y2;
            double weight = std::sqrt(x * x + y * y);
            double was = double(matrix_new[c1][c2]) / double(accuracy);
            if (was == 0) {
                matrix_new[c1][c2] = weight * accuracy;
                matrix_new[c2][c1] = weight * accuracy;
            } else {
                matrix_new[c1][c2] = std::min(weight, was);
                matrix_new[c2][c1] = matrix_new[c1][c2];
            }
        }
    }
    std::cout << SolutionB6(amount, matrix_new, edges_new);
    return 0;
}

Testing system use GNU C++20 10.2, runtime error with this test:

1
1 1
0

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文