60pts求助

P6348 [PA2011] Journeys

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

把加边变成有向边就可以了,虽然不太懂为什么


|