• POJ 2374 线段树建图+Dijkstra


    题意:
    这里写图片描述
    这里写图片描述

    思路:
    线段树+Dijkstra(要堆优化的)

    线段树要支持打标记
    一个栅栏 拆成两个点 :左和右
    新加一个栅栏的时候 看看左端点有没有被覆盖过
    如果有的话 就分别从覆盖的那条线段的左右向当前的左端点连一条边权为距离的边

    右端点同理

    跑一遍Dijkstra 就好啦

    复杂度:O(nlogn)

    //By SiriusRen
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=100500;
    int n,s,xx,tree[N*16],first[N],next[N*4],v[N*4],w[N*4],tot,dis[N],vis[N];
    struct Fence{int l,r;}fence[N];
    struct Node{int now,weight;Node(){}Node(int x,int y){now=x,weight=y;}}jy;
    bool operator < (Node a,Node b){return a.weight>b.weight;}
    void insert(int l,int r,int pos){
        if(l>=fence[xx].l&&r<=fence[xx].r){tree[pos]=xx;return;}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(mid<fence[xx].l)insert(mid+1,r,rson);
        else if(mid>=fence[xx].r)insert(l,mid,lson);
        else insert(l,mid,lson),insert(mid+1,r,rson);
    }
    int query(int l,int r,int pos,int x){
        if(l==r){return tree[pos];}
        int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
        if(tree[pos])tree[lson]=tree[rson]=tree[pos],tree[pos]=0;
        if(x<mid)return query(l,mid,lson,x);
        else return query(mid+1,r,rson,x);
    }
    void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
    void deal(){
        int tempx=query(-N,N,1,fence[xx].l);
        add(tempx<<1,xx<<1,abs(fence[tempx].l-fence[xx].l));
        add(tempx<<1|1,xx<<1,abs(fence[tempx].r-fence[xx].l));
        int tempy=query(-N,N,1,fence[xx].r);
        add(tempy<<1,xx<<1|1,abs(fence[tempy].l-fence[xx].r));
        add(tempy<<1|1,xx<<1|1,abs(fence[tempy].r-fence[xx].r));
        insert(-N,N,1);
    }
    void Dijkstra(){
        memset(dis,0x3f,sizeof(dis)),dis[0]=0;
        priority_queue<Node>pq;pq.push(jy);
        while(!pq.empty()){
            Node t=pq.top();pq.pop();
            if(vis[t.now])continue;
            vis[t.now]=1;
            for(int i=first[t.now];~i;i=next[i])
                if(!vis[v[i]]&&dis[v[i]]>dis[t.now]+w[i]){
                    dis[v[i]]=dis[t.now]+w[i];
                    pq.push(Node(v[i],dis[v[i]]));
                }
        }
    }
    int main(){
        scanf("%d%d",&n,&s);
        memset(first,-1,sizeof(first)),add(0,1,0);
        for(xx=1;xx<=n;xx++)scanf("%d%d",&fence[xx].l,&fence[xx].r),deal();
        xx++,fence[xx].l=fence[xx].r=s;deal(),add(xx<<1,xx<<1|1,0);
        Dijkstra();
        printf("%d
    ",dis[xx<<1|1]);
    }

    这里写图片描述

  • 相关阅读:
    201264
    asp.net 实现随机生成验证码
    数据库连接方式读取不到Excel数据值的解决方法
    如何对ArcSDE空间网格大小进行优化?
    坐标转换资料
    (转载)SDE命令行安装配置
    2008年的这些事儿
    注记多行显示问题的解决方法
    你的行为伤害了谁?
    oracle 数据备份(收藏)
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532184.html
Copyright © 2020-2023  润新知