• BZOJ3073 PA2011Journeys(线段树+bfs)


      线段树优化建图裸题。建两棵线段树,一棵表示入一棵表示出。对题中所给的边新建一个虚拟点,将两段区间拆成线段树上对应区间,出线段树中对应区间所表示的点向虚拟点连边权0的边,虚拟点向入线段树中对应区间所表示的点连边权1的边;线段树上的点之间连边权0的边(表示入的由父亲连向儿子,表示出的由儿子连向父亲),表示相同点的叶子节点(由入连向出)之间连边权0的边。01bfs即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define ll long long
    #define N 500010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,S,id[2][N],root[2],v[2][100],p[N*10],d[N*10],t,cnt;
    struct data{int to,nxt,len;
    }edge[N<<5];
    struct data2{int l,r;
    }tree[2][N<<3];
    deque<int> q;
    void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
    void build(int &k,int l,int r,int p)
    {
        k=++cnt;
        if (l==r) {id[p][l]=k;return;}
        int mid=l+r>>1;
        build(tree[p][k].l,l,mid,p);
        build(tree[p][k].r,mid+1,r,p);
        if (p==0) addedge(tree[p][k].l,k,0),addedge(tree[p][k].r,k,0);
        else addedge(k,tree[p][k].l,0),addedge(k,tree[p][k].r,0);
    }
    void find(int &k,int l,int r,int x,int y,int p)
    {
        if (l==x&&r==y) {v[p][++v[p][0]]=k;return;}
        int mid=l+r>>1;
        if (y<=mid) find(tree[p][k].l,l,mid,x,y,p);
        else if (x>mid) find(tree[p][k].r,mid+1,r,x,y,p);
        else find(tree[p][k].l,l,mid,x,mid,p),find(tree[p][k].r,mid+1,r,mid+1,y,p);
    }
    void bfs(int S)
    {
        d[S]=0;q.push_back(S);
        while (!q.empty())
        {
            int x=q.front();q.pop_front();
            for (int i=p[x];i;i=edge[i].nxt)
            if (d[x]+edge[i].len<d[edge[i].to])
            {
                d[edge[i].to]=d[x]+edge[i].len;
                if (edge[i].len) q.push_back(edge[i].to);
                else q.push_front(edge[i].to);
            }
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3073.in","r",stdin);
        freopen("bzoj3073.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read(),S=read();
        build(root[0],1,n,0);
        build(root[1],1,n,1);
        for (int i=1;i<=m;i++)
        {
            int a=read(),b=read(),c=read(),d=read();
            v[0][0]=v[1][0]=0;cnt++;
            find(root[0],1,n,a,b,0);
            for (int x=1;x<=v[0][0];x++) addedge(v[0][x],cnt,0);
            find(root[1],1,n,c,d,1);
            for (int x=1;x<=v[1][0];x++) addedge(cnt,v[1][x],1);
            v[0][0]=v[1][0]=0;cnt++;
            find(root[0],1,n,c,d,0);
            for (int x=1;x<=v[0][0];x++) addedge(v[0][x],cnt,0);
            find(root[1],1,n,a,b,1);
            for (int x=1;x<=v[1][0];x++) addedge(cnt,v[1][x],1);
        }
        for (int i=1;i<=n;i++) addedge(id[1][i],id[0][i],0);
        memset(d,42,sizeof(d));bfs(id[0][S]);
        for (int i=1;i<=n;i++) printf("%d
    ",d[id[0][i]]);
        return 0;
    }
  • 相关阅读:
    maven解决“Could not calculate build plan”问题
    HTTP中的重定向和请求转发的区别
    (转)《杂 文》 之 教你制作一份属于自己的简历
    (转)《SSO CAS单点系列》之 实现一个SSO认证服务器是这样的!
    (转)《SSO CAS单点系列》之 15分钟让你了解SSO技术到底是个什么鬼!
    (转)帮你深入理解OAuth2.0协议
    opengl库区分:glut、freeglut、glfw、glew、gl3w、glad
    OpenGL中的光照技术(翻译)
    [转]gluProject 和 gluUnproject 的详解
    英文版Ubuntu18.10安装搜狗输入法过程(图文并茂,亲自尝试!)
  • 原文地址:https://www.cnblogs.com/Gloid/p/9906215.html
Copyright © 2020-2023  润新知