CodeForces 787D--Legacy(最短路线段树优化建图)

时间:2020-07-10
本文章向大家介绍CodeForces 787D--Legacy(最短路线段树优化建图),主要包括CodeForces 787D--Legacy(最短路线段树优化建图)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:https://codeforces.com/contest/787/problem/D

题目大意:有n个星球,你有q个单向传送门

类型1,$u$  $v$  $w$,表示从$u$到$v$花费$w$

类型2,$u$  $l$   $r$  $w$,表示从$u$到区间$[l,r]$中的任意的星球,花费$w$

类型3,$u$  $l$   $r$  $w$,表示从$[l,r]$中任意的星球到$u$,花费$w$,

问从s开始到每个星球的最短距离,如果无法到达则输出-1

Examples

Input
3 5 1
2 3 2 3 17
2 3 2 2 16
2 2 2 3 3
3 3 1 1 12
1 3 3 17
Output
0 28 12 
Input
4 3 1
3 4 1 3 12
2 2 3 4 10
1 2 4 16
Output
0 -1 -1 12 

emmm,之前已经写过了一篇了,现在在做又WA了好几发QAQ。。。以下是以前写的博客,里面有详细的解说

https://blog.csdn.net/qq_43906000/article/details/102256830

主要就是用两颗线段树来对区间建立路径做个优化

贴一下代码吧QAQ

以下是AC代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;

#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define lc rt<<1
#define rc rt<<1|1
typedef long long ll;
const int mac=1e5+10;
const ll inf=1e18+10;

struct node
{
    int id;
    ll s;
    bool operator<(const node &a)const {
        return s>a.s;
    }
};
struct Edge
{
    int to,next,w;
}eg[mac*20];
ll dis[mac*10];
int head[mac*10],tree1[mac<<2],tree2[mac<<2];
int idx,pa[mac],pb[mac],num;
bool vis[mac*10];

void add(int u,int v,int w)
{
    eg[num]=Edge{v,head[u],w};
    head[u]=num++;
}

void build1(int l,int r,int rt)
{
    tree1[rt]=++idx;
    if (l==r){
        pa[l]=tree1[rt];
        return;
    }
    int mid=(l+r)>>1;
    build1(lson);build1(rson);
    add(tree1[rt],tree1[lc],0);
    add(tree1[rt],tree1[rc],0);
}

void build2(int l,int r,int rt)
{
    tree2[rt]=++idx;
    if (l==r){
        pb[l]=tree2[rt];
        add(pa[l],tree2[rt],0);
        return;
    }
    int mid=(l+r)>>1;
    build2(lson);build2(rson);
    add(tree2[lc],tree2[rt],0);
    add(tree2[rc],tree2[rt],0);
}

void update_to_range(int l,int r,int rt,int st,int L,int R,int w)
{
    if (l>=L && r<=R){
        add(pb[st],tree1[rt],w);
        return;
    }
    int mid=(l+r)>>1;
    if (mid>=L) update_to_range(lson,st,L,R,w);
    if (mid<R) update_to_range(rson,st,L,R,w);
}

void update_to_pos(int l,int r,int rt,int L,int R,int ed,int w)
{
    if (l>=L && r<=R){
        add(tree2[rt],pa[ed],w);
        return;
    }
    int mid=(l+r)>>1;
    if (mid>=L) update_to_pos(lson,L,R,ed,w);
    if (mid<R) update_to_pos(rson,L,R,ed,w);
}

void dij(int st)
{
    priority_queue<node>q;
    q.push(node{st,0});
    dis[st]=0;
    while (!q.empty()){
        node now=q.top();
        q.pop();
        int u=now.id;
        if (vis[u]) continue;
        vis[u]=true;
        for (int i=head[u]; i!=-1; i=eg[i].next){
            int v=eg[i].to;
            if (vis[v]) continue;
            if (dis[v]>dis[u]+1LL*eg[i].w){
                dis[v]=dis[u]+1LL*eg[i].w;
                q.push(node{v,dis[v]});
            }
        }
    }
}

int main(int argc, char const *argv[])
{
    //freopen("in.txt","r",stdin);
    int n,q,s;
    scanf ("%d%d%d",&n,&q,&s);
    memset(head,-1,sizeof head);
    build1(1,n,1); build2(1,n,1);
    for (int i=1; i<=q; i++){
        int id,u,v,w,l,r;
        scanf ("%d",&id);
        if (id==1) {
            scanf ("%d%d%d",&u,&v,&w);
            add(pb[u],pa[v],w);
        }
        else{
            scanf ("%d%d%d%d",&v,&l,&r,&w);
            if (id==2) update_to_range(1,n,1,v,l,r,w);
            else update_to_pos(1,n,1,l,r,v,w);
        }
    }
    for (int i=1; i<n*10; i++) dis[i]=inf;
    dij(pb[s]);
    for (int i=1; i<=n; i++){
        if (dis[pb[i]]==inf) printf("%d%c",-1,i==n?'\n':' ');
        else printf("%lld%c",dis[pb[i]],i==n?'\n':' ');
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lonely-wind-/p/13281124.html