zoukankan      html  css  js  c++  java
  • P5344 【XR-1】逛森林

    题意:可以进行区间间互相连边与单点连边,求从某起点到所有点的最短距离。

    先离线弄出树的形态,并保存可行的区间操作。

    然后就是喜闻乐见的树剖+线段树优化了。

    然而,毒瘤出题人把树剖卡成了不会tle便会mle。

    我会说我考试时被卡成傻逼了么

    于是预处理倍增进行连边即可,

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    using namespace std;
    typedef long long ll;
    const int N=5e4+10,M=13e5+10;
    struct node{
        int u1,v1,u2,v2,w;node(){};
        node(int _u1,int _v1,int _u2,int _v2,int _w){
            u1=_u1,v1=_v1,u2=_u2;v2=_v2;w=_w;
        }
    }ql[M];
    int n,m,s,t,tot,cnt,lg[N],f[N],dis[M<<1],d[N<<1],vis[M<<1],fa[N][16],in[N][16],out[N][16];
    priority_queue<pair<int,int> >q;vector<int> g[N<<1];vector<pair<int,int> >edge[M<<1];
    inline ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void add(int x,int y,int z){
        edge[x].push_back(make_pair(y,z));
    }
    inline void dijkstra(){
        memset(dis,0x3f,sizeof(dis));
        dis[s]=0;q.push(make_pair(0,s));
        while(q.size()){
            int x=q.top().second;q.pop();
            if(vis[x]) continue;vis[x]=1;
            for(int i=0;i<edge[x].size();i++){
                int y=edge[x][i].first,z=edge[x][i].second;
                if(dis[y]>dis[x]+z){
                    dis[y]=dis[x]+z;if(!vis[y]) q.push(make_pair(-dis[y],y));
                }
            }
        }
    }
    inline int get(int x){
        if(x==f[x]) return x;return f[x]=get(f[x]);
    }
    inline int lca(int x,int y){
        if(d[x]>d[y]) swap(x,y);
        for(int i=15;~i;i--) if(d[fa[y][i]]>=d[x]) y=fa[y][i];
        if(x==y) return x;
        for(int i=15;~i;i--) if(fa[y][i]!=fa[x][i]) y=fa[y][i],x=fa[x][i];
        return fa[x][0]; 
    }
    inline void dfs(int x,int fat){
        fa[x][0]=fat;d[x]=d[fat]+1;
        in[x][0]=out[x][0]=x;
        for(int i=1;i<=15;i++){fa[x][i]=fa[fa[x][i-1]][i-1];}
        for(int i=1;(1<<i)<=d[x];i++){
            in[x][i]=++cnt;out[x][i]=++cnt;
            add(in[x][i],in[x][i-1],0);
            add(out[x][i-1],out[x][i],0);
            add(in[x][i],in[fa[x][i-1]][i-1],0);
            add(out[fa[x][i-1]][i-1],out[x][i],0);
        }
        for(int i=0;i<g[x].size();i++){
            int y=g[x][i];if(y==fat) continue;
            dfs(y,x);
        }
    }
    inline void build(int v1,int u1,int w,int k){
        int j=0,u=u1,v;
        for(;(2<<(j))<=d[u1]-d[v1]+1;j++);
        int res=d[u1]-d[v1]+1-(1<<j);
        for(int i=20;~i;i--) if(res&(1<<i)) u=fa[u][i];
        if(k) v=in[u][j];else v=out[u][j];
        add(k?cnt:v,k?v:cnt,w);
        u=u1;if(k) v=in[u][j];else v=out[u][j];
        add(k?cnt:v,k?v:cnt,w);
    }
    int main(){
        n=read();m=read();s=read();cnt=n+1;
        for(int i=1;i<=n;i++) f[i]=i;
        for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;
        for(int i=1;i<=m;i++){
            int k=read(),u1=read(),v1=read(),u2,v2,w;
            if(k==1){
                u2=read();v2=read();w=read();
                if(get(u1)!=get(v1)||get(u2)!=get(v2)) continue;
                ql[++t]=node(u1,v1,u2,v2,w);
            }
            else if(k==2){
                int fu=get(u1),fv=get(v1);w=read();
                if(fu==fv) continue;
                g[u1].push_back(v1);
                g[v1].push_back(u1);
                add(u1,v1,w);add(v1,u1,w);
                f[fu]=fv;
            }
        }
        for(int i=1;i<=n;i++) if(!d[i]) dfs(i,0);
        for(int i=1;i<=t;i++){
            int u1=ql[i].u1,v1=ql[i].v1,u2=ql[i].u2,v2=ql[i].v2,w=ql[i].w;
            int lc1=lca(u1,v1),lc2=lca(u2,v2);cnt++;
            build(lc1,u1,0,0);build(lc1,v1,0,0);
            build(lc2,u2,w,1);build(lc2,v2,w,1);
        }
        dijkstra();for(int i=1;i<=n;i++) printf("%d ",(dis[i]==0x3f3f3f3f)?-1:dis[i]);
        return 0;
    }

    然后发现BZOJ4699具有90%的相似度,顺手a了,代码也不放了,读入改下就行了。

    不过发现榜首的大爷们都是一个log的,orzorz

  • 相关阅读:
    pthread线程内存布局
    用户空间实现线程 内核实现线程 线程的调度
    堆 虚拟内存
    Operating System-Thread(3)用户空间和内核空间实现线程
    Linux进程地址空间与虚拟内存
    虚拟地址
    物理内存,虚拟内存,进程地址空间
    CPU中MMU的作用
    进程地址空间与虚拟存储空间的理解
    虚拟地址空间
  • 原文地址:https://www.cnblogs.com/xtkm/p/10831181.html
Copyright © 2011-2022 走看看