Dijkstra 死循环求助
查看原帖
Dijkstra 死循环求助
932039
lzy20091001楼主2024/4/27 17:27
#include <cstring>
#include <iostream>
#include <bitset>
#include <vector>
#include <queue>

struct Edge
{
    int to, nxt, w;
};

struct Node // Dijkstra 堆优化中堆的元素
{
    int u, w;
    friend bool operator>(Node a, Node b) { return a.w > b.w; } // 自定义堆排序
};

int n, p, k, cnt_edge;
int dis[1005], head[1005];
Edge edge[100005];                                                   // 原图
std::bitset<1005> vis;                                               // dijkstra 判断
std::bitset<100005> t;                                               // 每次二分时的新图
std::priority_queue<Node, std::vector<Node>, std::greater<Node>> pq; // dijkstra 堆优化

void add_edge(int u, int v, int w) // 链式前向星
{
    edge[cnt_edge].to = v;
    edge[cnt_edge].w = w;
    edge[cnt_edge].nxt = head[u];
    head[u] = cnt_edge++;
}

void dijkstra()
{
    memset(dis, 0x3f, 4 * (n + 1));
    dis[1] = 0;
    pq.push({1, 0});

    while (!pq.empty())
    {
        int u = pq.top().u;
        pq.pop();
        if (u == n)
            return;
        if (vis[u])
            continue;
        vis[u] = true;
        for (int i = head[u]; i != -1; i = edge[i].nxt)
        {
            int v = edge[i].to, w = t[i];
            if (dis[v] > dis[u] + w)
            {
                // std::cout << u << " " << v << " " << dis[v] << " " << dis[u] << " " << w << std::endl;
                dis[v] = dis[u] + w;
                // std::cout << u << " " << v << " " << dis[v] << " " << dis[u] << " " << w << std::endl;
                pq.push({v, dis[v]});
            }
        }
    }
}

bool check(int x) // 二分判断
{
    vis.reset();
    for (int i = 0; i < cnt_edge; i++)
        t[i] = edge[i].w > x;
    while (!pq.empty())
        pq.pop();
    dijkstra();
    return dis[n] <= k;
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int l, r, ans = -1;

    std::cin >> n >> p >> k;
    memset(head, -1, sizeof(int) * (n + 1));
    for (int i = 1; i <= p; i++)
    {
        int a, b, l;
        std::cin >> a >> b >> l;
        add_edge(a, b, l);
        add_edge(b, a, l);
    }

    l = 0, r = 1000000;
    while (l <= r) // 二分
    {
        int m = (l + r) / 2;
        if (check(m))
        {
            ans = m;
            r = m + 1;
        }
        else
            l = m + 1;
    }

    std::cout << ans << "\n";

    return 0;
}
2024/4/27 17:27
加载中...