B612Dusk @ 2024-08-16 00:38:43
#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
const int N = 2e6 + 10;
inline int max(int x, int y) { return x > y ? x : y; }
inline int min(int x, int y) { return x < y ? x : y; }
inline void swap(int &x, int &y) { x ^= y ^= x ^= y; }
inline int read()
{
int t;
cin >> t;
return t;
}
int n, n_, m, st, pt[N << 1];
int nxt[N << 3], ver[N << 3], val[N << 3];
int head[N << 2], tot;
inline void add(int a, int b)
{
nxt[++ tot] = head[a], ver[tot] = b;
head[a] = tot;
}
struct Seg{
int l, r;
#define l(p) tr[p].l
#define r(p) tr[p].r
}tr[N << 3];
int rt, idx;
std::map<int, int> id;
#define mid (l(p) + r(p) >> 1)
void build(int p, int l, int r)
{
l(p) = l, r(p) = r, n_ = max(n_, p), idx = n_;
if(l == r) return id[l] = p, void();
build(p << 1, l, mid), build(p << 1 | 1, mid + 1, r);
add(p, p << 1), add(p, p << 1 | 1);
}
void copys(int p, int l, int r)
{
l(p + idx) = l, r(p + idx) = r, n_ = max(n_, p + idx);
if(l == r) return ;
copys(p << 1, l, mid), copys(p << 1 | 1, mid + 1, r);
add((p << 1) + idx, p + idx), add((p << 1 | 1) + idx, p + idx);
}
void cover(int p, int l, int r, int x)
{
if(l <= l(p) && r(p) <= r)
{
add(x, p); add(p, x);
return;
}
if(l <= mid) cover(p << 1, l, r, x);
if(r > mid) cover(p << 1 | 1, l, r, x);
}
void find(int p, int l, int r, int x)
{
if(l <= l(p) && r(p) <= r)
{
add(p + idx, x), add(x, p + idx);
return;
}
if(l <= mid) find(p << 1, l, r, x);
if(r > mid) find(p << 1 | 1, l, r, x);
}
struct node{
int pos, dis;
bool operator > (const node &a) const{
return dis > a.dis;
}
};
std::priority_queue<node, std::vector<node>, std::greater<node> > q;
bool vis[N << 4];
int dist[N << 4];
void dijkstra(int s)
{
memset(dist, 0x7f, sizeof dist);
dist[s] = 0;
q.push((node){s, 0});
while(!q.empty())
{
node x = q.top();
q.pop();
if(vis[x.pos]) continue;
vis[x.pos] = 1;
for(int i = head[x.pos]; i; i = nxt[i])
{
int y = ver[i];
if(dist[y] > dist[x.pos] + pt[y])
{
dist[y] = dist[x.pos] + pt[y];
q.push((node){y, dist[y]});
}
}
}
}
signed main()
{
// freopen("", "r", stdin);
// freopen("", "w", stdout);
std::ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
n = read(), m = read(), st = read();
build(1, 1, n), copys(1, 1, n);
for(int i = 1;i <= idx;i = -~i)
add(i, i + idx);
for(int i = 1;i <= m;i = -~i)
{
int l1 = read(), r1 = read(), l2 = read(), r2 = read();
pt[++ n_] = 1;
find(1, l1, r1, n_), cover(1, l2, r2, n_);
pt[++ n_] = 1;
find(1, l2, r2, n_), cover(1, l1, r1, n_);
}
dijkstra(id[st]);
for(int i = 1;i <= n;i = -~i) cout << dist[id[i]] << endl;
return 0;
}
正常思路
by B612Dusk @ 2024-08-16 12:07:02
把加边变成有向边就可以了,虽然不太懂为什么