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
vis
是白弄的吗?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