zoukankan      html  css  js  c++  java
  • 【BZOJ2125】—最短路(圆方树+树链剖分)

    传送门

    题意:询问仙人掌上2点之间最短路

    先建出圆方树,每个圆点到方点的距离为到这个环最高点的最短距离
    每次询问分类讨论一下圆点方点
    如果是方点的话找到到这个环的那个入点,计算2个入点之间最短距离就可以了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<18|1;
    #define file freopen("lx.cpp","r",stdin);
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
        char ch=gc();
        int res=0,f=0;
        while(!isdigit(ch))f^=(ch=='-'),ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?-res:res;
    }
    const int N=40004;
    struct Graph{
        int cnt,adj[N],nxt[N<<1],to[N<<1],val[N<<1];
        inline void add(int u,int v,int w){
            nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w;
        }
        inline void addedge(int u,int v,int w){
            add(u,v,w),add(v,u,w);
        }
    }G,T;
    int n,m,q;
    int dfn[N],fa[N],dep[N],bel,plc[N],dis[N],low[N],stk[N],tot,len[N];
    inline void buildRec(int u,int v,int w){
        int top=dep[v]-dep[u]+1,sum=w,dt=0;
        for(int i=v;i!=u;i=fa[i])stk[top--]=i,sum+=dis[i]-dis[fa[i]];
        bel++,len[bel]=sum,stk[1]=u;
        for(int i=1;i<=dep[v]-dep[u]+1;i++){
            int d=min(dt,sum-dt);
            T.addedge(bel,stk[i],d);
            plc[stk[i]]=d==dt;
            dt+=dis[stk[i+1]]-dis[stk[i]];
        }
    }
    void tarjan(int u){
        dfn[u]=low[u]=++tot;
        for(int e=G.adj[u];e;e=G.nxt[e]){
            int v=G.to[e];
            if(v==fa[u])continue;
            if(!dfn[v]){
                fa[v]=u,dep[v]=dep[u]+1,dis[v]=dis[u]+G.val[e];
                tarjan(v),low[u]=min(low[u],low[v]);
            }
            else low[u]=min(low[u],dfn[v]);
            if(dfn[u]<low[v])T.addedge(u,v,G.val[e]);
        }
        for(int e=G.adj[u];e;e=G.nxt[e]){
            int v=G.to[e];
            if(v==fa[u])continue;
            if(fa[v]!=u&&dfn[u]<dfn[v])buildRec(u,v,G.val[e]);
        }
    }
    namespace SLPF{
        int pos[N],idx[N],siz[N],son[N],dis[N],fa[N],top[N],dep[N],tot;
        void dfs1(int u){
            siz[u]=1;
            for(int e=T.adj[u];e;e=T.nxt[e]){
                int v=T.to[e];
                if(v==fa[u])continue;
                dep[v]=dep[u]+1,fa[v]=u,dis[v]=dis[u]+T.val[e];
                dfs1(v),siz[u]+=siz[v];
                if(siz[u]>siz[son[u]])son[u]=v;
            }
        }
        void dfs2(int u,int tp){
            pos[u]=++tot,idx[tot]=u,top[u]=tp;
            if(son[u])dfs2(son[u],tp);
            for(int e=T.adj[u];e;e=T.nxt[e]){
                int v=T.to[e];
                if(v==fa[u]||v==son[u])continue;
                dfs2(v,v);
            }
        }
        inline int Lca(int u,int v){
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]])swap(u,v);
                u=fa[top[u]];
            }return dep[u]>dep[v]?v:u;
        }
        inline int jump(int u,int g){
            int pre;
            while(top[u]!=top[g]){
                pre=top[u],u=fa[top[u]];
            }
            return u==g?pre:idx[pos[g]+1];
        }
        inline int query(int u,int v){
            int lca=Lca(u,v);
            if(lca<=n)return dis[u]+dis[v]-2*dis[lca];
            int sonu=jump(u,lca),sonv=jump(v,lca);
            int du=dis[sonu]-dis[lca],dv=dis[sonv]-dis[lca];
            if(plc[sonu])du=len[lca]-du;if(plc[sonv])dv=len[lca]-dv;
            if(du<dv)swap(du,dv);
            return min(du-dv,len[lca]-du+dv)+dis[u]-dis[sonu]+dis[v]-dis[sonv];
        }
    }
    int main(){
        //file;
        bel=n=read(),m=read(),q=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read(),w=read();
            G.addedge(u,v,w);
        }
        tarjan(1);
        SLPF::dfs1(1),SLPF::dfs2(1,1);
        while(q--){
            int u=read(),v=read();
            cout<<SLPF::query(u,v)<<'
    ';
        }
    }
    
  • 相关阅读:
    CMake使用教程
    非常陌生的cmake
    C#绘制立体三维饼状图
    有关C,C++,C#, Java的图形图像处理类库 整理(未完待续)
    Eclipse安装Maven插件报错
    WebLogic11g-常用运维操作
    WebLogic之eclipse安装WebLogic插件
    The server does not support version 3.0 of the J2EE Web module specification
    Project facet Java version 1.8 is not supported解决记录
    Weblogic部署项目三种方式
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145579.html
Copyright © 2011-2022 走看看