zoukankan      html  css  js  c++  java
  • [Codeforces 787D] Legacy

    [题目链接]

              https://codeforces.com/contest/787/problem/D

    [算法]

            线段树优化建边 ,  然后用Dijkstra算法求单源最短路

            时间复杂度 : O((N + M)logN)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 2e5 + 10;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const ll inf = 1e15;
    
    struct node
    {
            int lc , rc;
    } a[MAXN * 10];
    struct edge
    {
            int to , w , nxt;
    } e[MAXN << 4];
    
    int tot , cnt , n , q , s;
    int head[MAXN * 10] , root[2];
    bool visited[MAXN * 10];
    ll dist[MAXN * 10];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int x , int y , int w)
    {
            ++cnt;
            e[cnt] = (edge){y , w , head[x]};
            head[x] = cnt;
    }
    inline void buildA(int &now , int l , int r)
    {
            if (l == r)
            {
                    now = l;
                    return;
            }        
            now = ++tot;
            int mid = (l + r) >> 1;
            buildA(a[now].lc , l , mid);
            buildA(a[now].rc , mid + 1 , r);
            addedge(now , a[now].lc , 0);
            addedge(now , a[now].rc , 0);
    }
    inline void buildB(int &now , int l , int r)
    {
            if (l == r)
            {
                    now = l;
                    return;
            }
            now = ++tot;
            int mid = (l + r) >> 1;
            buildB(a[now].lc , l , mid);
            buildB(a[now].rc , mid + 1 , r);
            addedge(a[now].lc , now , 0);
            addedge(a[now].rc , now , 0);        
    }
    inline void updateA(int now , int l , int r , int ql , int qr , int u , int w)
    {
            if (l == ql && r == qr)
            {
                    addedge(u , now , w);
                    return;        
            }        
            int mid = (l + r) >> 1;
            if (mid >= qr) updateA(a[now].lc , l , mid , ql , qr , u , w);
            else if (mid + 1 <= ql) updateA(a[now].rc , mid + 1 , r , ql , qr , u , w);
            else
            {
                    updateA(a[now].lc , l , mid , ql , mid , u , w);
                    updateA(a[now].rc , mid + 1 , r , mid + 1 , qr , u , w);
            }
    }
    inline void updateB(int now , int l , int r , int ql , int qr , int u , int w)
    {
            if (l == ql && r == qr)
            {
                    addedge(now , u , w);
                    return; 
            }
            int mid = (l + r) >> 1;
            if (mid >= qr) updateB(a[now].lc , l , mid , ql , qr , u , w);
            else if (mid + 1 <= ql) updateB(a[now].rc , mid + 1 , r , ql , qr , u , w);
            else
            {
                    updateB(a[now].lc , l , mid , ql , mid , u , w);
                    updateB(a[now].rc , mid + 1 , r , mid + 1 , qr , u , w);
            }
    }
    inline void dijkstra(int s)
    {
            priority_queue< pair<ll , ll> , vector< pair<ll , ll> > , greater< pair<ll , ll> > > q;
            dist[s] = 0;
            q.push(make_pair(0 , s));
            while (!q.empty())
            {
                    int u = q.top().second;
                    q.pop();
                    if (visited[u]) continue;
                    visited[u] = true;
                    for (int i = head[u]; i; i = e[i].nxt)
                    {
                            int v = e[i].to , w = e[i].w;
                            if (dist[u] + w < dist[v])
                            {
                                    dist[v] = dist[u] + w;
                                    q.push(make_pair(dist[v] , v));
                            }
                    }
            }
    }
    
    int main()
    {
            
            read(n); read(q); read(s);
            tot = n;
            buildA(root[0] , 1 , n);
            buildB(root[1] , 1 , n);
            while (q--)
            {
                    int type;
                    read(type);
                    if (type == 1)
                    {
                            int u , v , w;
                            read(u); read(v); read(w);
                            addedge(u , v , w);
                    }
                    if (type == 2)
                    {
                            int l , r , v , w;
                            read(v); read(l); read(r); read(w);
                            updateA(root[0] , 1 , n , l , r , v , w);
                    } 
                    if (type == 3)
                    {
                            int l , r , v , w;
                            read(v); read(l); read(r); read(w);
                            updateB(root[1] , 1 , n , l , r , v , w);
                    }
            }
            for (int i = 1; i <= tot; i++) dist[i] = inf;
            dijkstra(s);
             for (int i = 1; i <= n; i++) printf("%lld " , dist[i] == inf ? -1 : dist[i]);
            
            return 0; 
        
    }
  • 相关阅读:
    正则表达式
    JS逻辑算法
    js函数
    JS运算符的应用
    JS课堂笔记
    json模块学习
    什么是面向对象,以及如何定义对象,实例化对象
    什么是面向过程,以及代码展示
    什么是元类,以及用type类来产生类.
    python下载安装
  • 原文地址:https://www.cnblogs.com/evenbao/p/10146465.html
Copyright © 2011-2022 走看看