zoukankan      html  css  js  c++  java
  • bzoj3073: [Pa2011]Journeys

    Description

    Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路。N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a,b),(c,d)表示,对于任意两个国家x,y,如果a<=x<=b,c<=y<=d,那么在xy之间建造一条道路。Seter保证一条道路不会修建两次,也保证不会有一个国家与自己之间有道路。
    Seter好不容易建好了所有道路,他现在在位于P号的首都。Seter想知道P号国家到任意一个国家最少需要经过几条道路。当然,Seter保证P号国家能到任意一个国家。
     
    注意:可能有重边

    Input

    第一行三个数N,M,P。N<=500000,M<=100000。
    后M行,每行4个数a,b,c,d。1<=a<=b<=N,1<=c<=d<=N。

    Output

    N行,第i行表示P号国家到第i个国家最少需要经过几条路。显然第P行应该是0。
    将点建成两棵线段树,记为A,B,以后所有连边为单向边,A中每个节点到父节点连单向边,边权0,B中每个节点到子节点连边,边权0,B中每个节点到A中相同位置的点连边,边权0,对每一组边,新开一个节点x,在A中查出[a,b]对应的点,到x连边,边权1/2,x到B中[c,d]对应的点连边,边权1/2
    新建的图中A中的叶节点对应了原图中的点,在原图中走一条边对应新图中从A的叶节点出发,经过一个x节点,到达B,再走回A
    然后就是01边权最短路了。。可以用dijkstra+deque维护,时空复杂度都和边数同阶,为O(Mlogn+n)
    #include<bits/stdc++.h>
    char buf[10000007],*ptr=buf-1;
    int _(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    int n,m,k,mx=2;
    int l[2555555],idp;
    bool d[2555555],ev[30000007];
    int es[30000007],enx[30000007],e0[2555555],ep=2;
    void ae(int a,int b,int c){
        es[ep]=b;enx[ep]=e0[a];ev[ep]=c;e0[a]=ep++;
    }
    void ins1(int l,int r,int w){
        for(l+=mx-1,r+=mx+1;l^r^1;l>>=1,r>>=1){
            if(~l&1)ae(l^1,w,1);
            if(r&1)ae(r^1,w,1);
        }
    }
    void ins2(int l,int r,int w){
        for(l+=mx-1,r+=mx+1;l^r^1;l>>=1,r>>=1){
            if(~l&1)ae(w,(l^1)+mx*2,1);
            if(r&1)ae(w,(r^1)+mx*2,1);
        }
    }
    std::deque<int>q;
    int main(){
        fread(buf,1,sizeof(buf),stdin);
        n=_();m=_();k=_();
        while(mx<n+1)mx<<=1;
        idp=mx*4+1;
        for(int i=mx-1;i;--i){
            ae(i<<1,i,0),ae(i<<1^1,i,0);
            ae(mx*2+i,mx*2+(i<<1),0),ae(mx*2+i,mx*2+(i<<1^1),0);
        }
        for(int i=1;i<mx*2;++i)ae(i+mx*2,i,0);
        for(int i=0,a,b,c,d;i<m;++i){
            a=_();b=_();c=_();d=_();
            ++idp;
            ins1(a,b,idp);
            ins2(c,d,idp);
            ++idp;
            ins1(c,d,idp);
            ins2(a,b,idp);
        }
        memset(l,0x3f,sizeof(int)*(idp+2));
        q.push_back(k+mx);l[k+mx]=0;
        while(!q.empty()){
            int w=q.front();q.pop_front();
            if(d[w])continue;
            d[w]=1;
            for(int i=e0[w];i;i=enx[i]){
                int u=es[i];
                if(ev[i]){
                    if(l[u]>l[w]+1)l[u]=l[w]+1,q.push_back(u);
                }else{
                    if(l[u]>l[w])l[u]=l[w],q.push_front(u);
                }
            }
        }
        for(int i=1;i<=n;++i)printf("%d
    ",l[i+mx]>>1);
        return 0;
    }
  • 相关阅读:
    CDOJ 92 – Journey 【LCA】
    LCA-Tarjan算法
    【模板】无向图的割顶
    Codeforces 190E
    TwoSAT算法模板
    【转】STL之二分查找 (Binary search in STL)
    【转】数论模板
    【转】计算几何模板
    【转】string常用函数
    Codeforces 245G Suggested Friends
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6339933.html
Copyright © 2011-2022 走看看