求助简单最短路!

P1462 通往奥格瑞玛的道路

rainygame @ 2023-10-15 12:24:51

思路:

首先第一次 Dijkstra 求出每个结点所需要消耗的最小血量,即求出可否到达这个结点。

第二次 Dijkstra 是在可以到达的结点中跑最短路,注意这里求的是路径中最大值(这个应该是可以 Dijkstra 的)。

样例可过,hack 可过,但 WA 90。

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MAXN 10001

int n, m, b, u, v, w;
int f[MAXN], minn[MAXN], dis[MAXN];
vector<pair<int, int>> e[MAXN];
bitset<MAXN> vis;

struct Node{
    int u, dis;
    bool operator<(Node b)const{
        return dis > b.dis;
    }
};
priority_queue<Node> pq;

void dijkstra1(){
    minn[1] = 0;
    pq.push({1, 0});
    while (!pq.empty()){
        u = pq.top().u;
        pq.pop();
        if (vis.test(u)) continue;
        vis.set(u);

        for (auto i: e[u]){
            v = i.first;
            w = i.second;
            if (minn[v] > minn[u] + w){
                minn[v] = minn[u] + w;
                pq.push({v, minn[v]});
            }
        }
    }
}

void dijkstra2(){
    dis[1] = f[1];
    pq.push({1, 0});
    while (!pq.empty()){
        u = pq.top().u;
        pq.pop();
        if (vis.test(u)) continue;
        vis.set(u);

        for (auto i: e[u]){
            v = i.first;
            if (minn[v] <= b && dis[v] > max(dis[u], f[v])){
                dis[v] = max(dis[u], f[v]);
                pq.push({v, dis[v]});
            }
        }
    }
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m >> b;
    for (int i(1); i<=n; ++i) cin >> f[i];
    while (m--){
        cin >> u >> v >> w;
        e[u].push_back(make_pair(v, w));
        e[v].push_back(make_pair(u, w));
    }

    memset(minn, 0x3f, sizeof(minn));
    dijkstra1();

    memset(dis, 0x3f, sizeof(dis));
    vis.reset();
    dijkstra2();

    if (dis[n] == 0x3f3f3f3f3f3f3f3f) cout << "AFK";
    else cout << dis[n];

    return 0;
}

by Xiphi @ 2023-10-15 12:36:47

首先一个点只能走一次,其次存边的数组要开两倍。


by Xiphi @ 2023-10-15 12:37:15

*两倍及以上


by Xiphi @ 2023-10-15 12:38:54

@rainygame


by rainygame @ 2023-10-15 12:43:15

@gz_jcxy

  1. 你当我的 vis 是白弄的吗?
  2. 我用的是邻接表而不是链式前向星。

by linxuanrui @ 2023-10-15 13:55:59

@rainygame

hack:

4 4 5
1
1
4
1
1 2 3
1 3 2
2 4 3
3 4 1

你的思路可能有点问题。

一条路径能到不代表所有路径能到。

上面的 hack 应输出 3,你的代码输出了 1


|