[CF786B] Legacy

[CF786B] Legacy - 线段树优化建图,最短路

Description

有三种操作:1.进行单点与单点连有向边 2.进行单点与区间连有向边 3.进行区间与单点连有向边。求最短路。

Solution

发现没有区间和区间,这暗示的够明显了,线段树优化建图即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

#ifndef _SP_H_
#define _SP_H_

#include <bits/stdc++.h>
using namespace std;
#define reset(x) memset(x, 0, sizeof x)
#define reset3f(x) memset(x, 0x3f, sizeof x)
namespace sp
{
    const int N = 2e+6 + 5;
    vector<pair<int, int>> g[N];
    int n, v0 = 1, d[N], v[N];
    void make(int t1, int t2, int t3)
    {
        g[t1].push_back(make_pair(t2, t3));
    }
    void reset_graph()
    {
        for (int i = 0; i <= n; i++)
            g[i].clear();
    }
    void solve()
    {
        priority_queue<pair<int, int>> qu;
        reset3f(d);
        reset(v);
        d[v0] = 0;
        qu.push(make_pair(0, v0));
        while (qu.size())
        {
            int p = qu.top().second, r = qu.top().first;
            qu.pop();
            if (r + d[p])
                continue;
            for (int i = 0; i < g[p].size(); i++)
            {
                int q = g[p][i].first, w = g[p][i].second;
                if (d[q] > d[p] + w)
                {
                    d[q] = d[p] + w;
                    qu.push(make_pair(-d[q], q));
                }
            }
        }
    }
} // namespace sp
#endif

int n;

void solvesp(int s)
{
    sp::solve();
    sp::v0 = s;
    sp::n = n * 12;
    sp::solve();
    for (int i = 1; i <= n; i++)
        if (sp::d[i] <= 1e15)
            cout << sp::d[i] << " ";
        else
            cout << -1 << " ";
}

void make(int u, int v, int w)
{
    sp::make(u, v, w);
}

void build(int p, int l, int r)
{
    if (l == r)
    {
        int i = l;
        make(p + 4 * n, i, 0);
        make(i, p + 8 * n, 0);
    }
    else
    {
        build(p * 2, l, (l + r) / 2);
        build(p * 2 + 1, (l + r) / 2 + 1, r);
        make(p + 4 * n, p * 2 + 4 * n, 0);
        make(p + 4 * n, p * 2 + 1 + 4 * n, 0);
        make(p * 2 + 4 * n + 4 * n, p + 4 * n + 4 * n, 0);
        make(p * 2 + 1 + 4 * n + 4 * n, p + 4 * n + 4 * n, 0);
    }
}

void query(int p, int l, int r, int ql, int qr, vector<int> &ans)
{
    if (l > qr || r < ql)
        return;
    if (l >= ql && r <= qr)
    {
        ans.push_back(p);
    }
    else
    {
        query(p * 2, l, (l + r) / 2, ql, qr, ans);
        query(p * 2 + 1, (l + r) / 2 + 1, r, ql, qr, ans);
    }
}

vector<int> getset(int l, int r)
{
    vector<int> ans;
    query(1, 1, n, l, r, ans);
    return ans;
}

signed main()
{
    ios::sync_with_stdio(false);

    int q, s;
    cin >> n >> q >> s;
    build(1, 1, n);
    for (int i = 1; i <= q; i++)
    {
        int t;
        cin >> t;
        if (t == 1)
        {
            int u, v, w;
            cin >> u >> v >> w;
            make(u, v, w);
        }
        else if (t == 2)
        {
            int u, l, r, w;
            cin >> u >> l >> r >> w;
            auto vec = getset(l, r);
            for (auto i : vec)
                make(u, i + 4 * n, w);
        }
        else if (t == 3)
        {
            int u, l, r, w;
            cin >> u >> l >> r >> w;
            auto vec = getset(l, r);
            for (auto i : vec)
                make(i + 8 * n, u, w);
        }
    }
    solvesp(s);
}
原文地址:https://www.cnblogs.com/mollnn/p/14361264.html