zoukankan      html  css  js  c++  java
  • 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]);
    }

    这里写图片描述

  • 相关阅读:
    LeetCode 242. Valid Anagram (验证变位词)
    LeetCode 205. Isomorphic Strings (同构字符串)
    LeetCode 204. Count Primes (质数的个数)
    LeetCode 202. Happy Number (快乐数字)
    LeetCode 170. Two Sum III
    LeetCode 136. Single Number (落单的数)
    LeetCode 697. Degree of an Array (数组的度)
    LeetCode 695. Max Area of Island (岛的最大区域)
    Spark中的键值对操作
    各种排序算法总结
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532184.html
Copyright © 2011-2022 走看看