[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 << " ";
    }
}

相关文章:

  • 2021-05-17
  • 2021-10-07
  • 2021-07-14
  • 2021-06-07
  • 2022-12-23
  • 2022-12-23
  • 2021-11-09
  • 2022-01-26
猜你喜欢
  • 2021-09-15
  • 2022-02-16
  • 2021-11-08
相关资源
相似解决方案