题目链接:https://ac.nowcoder.com/acm/contest/884/J
题意:给你n个顶点的图,能把期中k条边置为0,给定起点,终点,求最短路
题解:把它当成一个k+1层的图,到下一层时,这条边的值为0,dis[i][j]表示第j层,起点到第i个点的距离,可以用spfa
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
typedef long long ll;
using namespace std;
ll dis[1050][1050], vis[1050][1050];
struct node
{
ll to, val;
};
vector<node>v[1050];
void spfa(ll s, ll k)
{
memset(dis, 0x3f3f3f3f3f3f3f3f, sizeof(vis));
memset(vis, 0, sizeof(vis));
dis[s][0] = 0;
vis[s][0] = 1;
queue<ll>q;
q.push(s);
q.push(0);
while (!q.empty())
{
ll u = q.front(); q.pop();
ll j = q.front(); q.pop();
for (ll i = 0; i<v[u].size(); i++)
{
ll vv = v[u][i].to;
if (dis[u][j] + v[u][i].val<dis[vv][j])
{
dis[vv][j] = dis[u][j] + v[u][i].val;
if (!vis[vv][j])
{
vis[vv][j] = 1;
q.push(vv);
q.push(j);
}
}
if (j<k&&dis[u][j]<dis[vv][j + 1])
{
dis[vv][j + 1] = dis[u][j];
if (!vis[vv][j + 1])
{
vis[vv][j + 1] = 1;
q.push(vv);
q.push(j + 1);
}
}
}
vis[u][j] = 0;
}
}
int main()
{
ll n, m, s, t, k;
scanf("%lld %lld %lld %lld %lld", &n, &m, &s, &t, &k);
for (int i = 1; i <= m; i++)
{
ll x, y, z;
scanf("%lld %lld %lld", &x, &y, &z);
v[x].push_back({ y,z });
v[y].push_back({ x,z });
}
spfa(s, k);
ll ansmin = 0x3f3f3f3f3f3f3f3f;
for (ll i = 0; i <= k; i++)
{
ansmin = min(ansmin, dis[t][i]);
}
printf("%lld\n", ansmin);
}
本文介绍了一种在图中寻找最短路径的优化算法,特别适用于可以将部分边权重置为0的情况。通过构建k+1层图,利用SPFA算法,实现了在考虑特定边权重变化下的高效路径搜索。
J-free&spm=1001.2101.3001.5002&articleId=98034632&d=1&t=3&u=15498016d4f94c66a5ea6ff5f8727aed)
2660

被折叠的 条评论
为什么被折叠?



