[CF1486E] Paired Payment - 分层图最短路
Description
给一张无向图,一次只能同时走两步,权值为两条边的边权和的平方。求1到其他每个点的最短距离。达不到就输出-1。边权<50。
Solution
考虑到边权很小,分层图最短路
状态记录当前点,当前经过边数的奇偶性,上一条边的边权
#include <bits/stdc++.h>
using namespace std;
int d[100005][3][55];
bool v[100005][3][55];
vector<pair<int, int>> g[100005];
void dijkstra()
{
struct Node
{
int d, x, y, z;
bool operator<(const Node &rhs) const
{
return d > rhs.d;
}
};
priority_queue<Node> que;
que.push({0, 1, 0, 1});
memset(d, 0x3f, sizeof d);
d[1][0][1] = 0;
while (que.size())
{
auto [_, x, y, z] = que.top();
que.pop();
if (v[x][y][z])
continue;
v[x][y][z] = 1;
int u = x;
for (auto [v, w] : g[u])
{
if (y == 0)
{
if (d[v][1][w] > d[u][0][z])
{
d[v][1][w] = d[u][0][z];
que.push({d[v][1][w], v, 1, w});
}
}
else
{
if (d[v][0][w] > d[u][1][z] + (z + w) * (z + w))
{
d[v][0][w] = d[u][1][z] + (z + w) * (z + w);
que.push({d[v][0][w], v, 0, w});
}
}
}
}
}
signed main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({v, w});
g[v].push_back({u, w});
}
dijkstra();
for (int i = 1; i <= n; i++)
{
int ans = 2e9;
for (int j = 1; j <= 50; j++)
ans = min(ans, d[i][0][j]);
if (ans < 1e9)
cout << ans << " ";
else
cout << -1 << " ";
}
}