专栏文章
题解:P12332 [蓝桥杯 2023 省 Java B] 魔法阵
P12332题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mink8sfa
- 此快照首次捕获于
- 2025/12/02 03:46 3 个月前
- 此快照最后确认于
- 2025/12/02 03:46 3 个月前
题目传送门
观察到 极小,所以你直接考虑对原图建分层图。考虑再分层图上的两种转移(设层数 ):
- 这条边没选,需要满足 或 ,那么直接在第 层图转移。转移时边权按原边权算。
- 这条边选了,需要满足 ,那么从第 层图转移到第 层图,转移时边权按 算。
答案即为 。
实际上只需要在松弛更新的时候考虑这两种转移即可,根本不需要把分层图建出来。直接硬跑 dij 或 已死算法spfa 都能过。
CPP#include <bits/stdc++.h>
using namespace std;
#define il inline
#define mkp make_pair
#define pi pair<int, int>
typedef long long ll;
const int N = 1e3 + 10, K = 11;
int f[N][K], inf = 1e9, n, m, k;
queue<pi> q;
vector<pi> g[N];
bool inque[N][K];
il void spfa(int s)
{
for(int i = 0;i < n;++i)
for(int j = 0;j <= k;++j)
f[i][j] = inf;
f[s][0] = 0;
inque[s][0] = 1;
q.push(mkp(s, 0));
while(q.size())
{
pi cur = q.front();
q.pop();
int u = cur.first, j = cur.second;
inque[u][j] = 0;
for(auto vv : g[u])
{
int v = vv.first, w = vv.second;
if((j == 0 || j == k) && f[v][j] > f[u][j] + w)
{
f[v][j] = f[u][j] + w;
if(!inque[v][j])
{
q.push(mkp(v, j));
inque[v][j] = 1;
}
}
if(j < k && f[v][j + 1] > f[u][j])
{
f[v][j + 1] = f[u][j];
if(!inque[v][j + 1])
{
q.push(mkp(v, j + 1));
inque[v][j + 1] = 1;
}
}
}
}
}
int main()
{
cin >> n >> k >> m;
while(m--)
{
int u, v, w;
cin >> u >> v >> w;
g[u].push_back(mkp(v, w));
g[v].push_back(mkp(u, w));
}
spfa(0);
cout << min(f[n - 1][0], f[n - 1][k]);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...