美文网首页
一道最短路建模

一道最短路建模

作者: TimeMage | 来源:发表于2017-04-04 23:02 被阅读11次

    题目链接:http://codeforces.com/contest/787/problem/D
    需要用上线段树,我用的是zkw,
    注意边的数量是nlogn的
    题解:

    • 存在一些边是点到一个连续区间的。
    • 如果把点到区间的边都看成挨个挨个连,边的数量会非常大会超时
    • 如果设立些辅助点和辅助边,辅助边的值为0,点到区间的边步直接连在点上,而是连到辅助点上。可以做到把一个区间边的数量由O(n)级降到O(log(n))级的。
      代码(除了zkw其他都是自己写的)
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1<<18;
    const int DBG = 0;
    struct Edge{
        int to;
        ll d;
        Edge* next;
    }*head[MAXN*2], e[MAXN*10];
    bool vis[MAXN*2];
    ll dis[MAXN*2];
    int ne, n, q, s, M;
    int getB(int x) {
        int ret = 1;
        while(ret<x) ret<<=1;
        return ret;
    }
    inline void addedge(int fr, int to, int d) {
        e[ne] = (Edge){to, d, head[fr]};
        head[fr] = e+ne++;
    }
    void addinterval(int u, int l, int r, int w, int t) {
        for(l=l+M-1, r=r+M+1, u=u|M; l^r^1; l>>=1, r>>=1) {
            if(~l&1) {
                if(t==2) addedge(u, l^1, w);
                else addedge((l^1)|MAXN, u, w);
            }
            if(r&1) {
                if(t==2) addedge(u, r^1, w);
                else addedge((r^1)|MAXN, u, w);
            }
        }
    }
    void Dijkstra(int s) {
        memset(dis, 0x3f, sizeof(dis));
        priority_queue<pair<ll, int> > pq;
        dis[s] = 0;
        pq.push(make_pair(0ll,s));
        while(pq.size()) {
            pair<ll, int> pu = pq.top();
            pq.pop();
            int u=pu.second;
            if(vis[u]) continue;
            vis[u] = true;
            if(DBG) printf("sel %d\n", u);
            for(Edge* p=head[u]; p; p=p->next) {
                if(dis[p->to]>dis[u]+p->d) {
                    dis[p->to] = dis[u]+p->d;
                    pq.push(make_pair(-dis[p->to], p->to));
                }
            }
        }
    }
    int main() {
        scanf("%d%d%d", &n, &q, &s);
        M = getB(n+2);
        for(int i=1; i<M; ++i) {
            addedge(i, i<<1, 0);
            addedge(i, i<<1|1, 0);
            addedge(i<<1|MAXN, i|MAXN, 0);
            addedge(i<<1|1|MAXN, i|MAXN, 0);
        }
        for(int i=0; i<M; ++i) {
            addedge(i|M, i|M|MAXN, 0);
            addedge(i|M|MAXN, i|M, 0);
        }
        while(q--) {
            int t, v, l, r, w;
            scanf("%d%d", &t, &v);
            if(t==1) {
                scanf("%d%d", &l, &w);
                addedge(M|v, M|l, w);
            }
            else {
                scanf("%d%d%d", &l, &r, &w);
                addinterval(v, l, r, w, t);
            }
        }
        Dijkstra(s|M);
        for(int i=1; i<n+1; ++i)
            printf("%I64d%c", vis[M|i]?dis[M|i]:-1ll, i==n?'\n':' ');
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:一道最短路建模

          本文链接:https://www.haomeiwen.com/subject/atuzottx.html