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