zoukankan      html  css  js  c++  java
  • 洛谷4320:道路相遇——题解

    https://www.luogu.com.cn/problem/P4320

    BZOJ5329: [SDOI2018]战略游戏——题解的弱化版,但是我交上去RE了,猜测是复杂度不对,懒得再去算了于是把树链剖分拿了过来。

    是的水了一篇博客

    #include<cmath>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=2e6+5;
    const int M=2e6+5;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int u[M],v[M],nxt[M];
        int cnt,head[N];
        void init(){
            cnt=0;memset(head,0,sizeof(head));
        }
        void add(int U,int V){
            u[++cnt]=U;v[cnt]=V;nxt[cnt]=head[U];head[U]=cnt;
        }
    }e,g;
    int n,m,T,w[N];
    int dfn[N],low[N],to[N],t,l;
    stack<int>q;
    void tarjan(int u,int f){
        dfn[u]=low[u]=++t;
        for(int i=g.head[u];i;i=g.nxt[i]){
            int v=g.v[i];
            if(!dfn[v]){
                q.push(i);tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]){
                    int num;l++;
                    do{
                        num=q.top();q.pop();
                        int x=g.u[num],y=g.v[num];
                        if(to[x]!=l){
                            to[x]=l;
                            e.add(x,l+n);e.add(l+n,x);
                        }
                        if(to[y]!=l){
                            to[y]=l;
                            e.add(y,l+n);e.add(l+n,y);
                        }
                    }while(num!=i);
                }
            }else if(low[u]>dfn[v]&&f!=v){
                q.push(i);low[u]=dfn[v];
            }
        }
    }
    bool is_square(int x){
        return x>n;
    }
    int tot,fa[N],pos[N],idx[N],size[N],son[N],dep[N],top[N],val[N];
    void dfs1(int u){
        size[u]=1;
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(fa[u]==v)continue;
            fa[v]=u;dep[v]=dep[u]+1;
            dfs1(v);size[u]+=size[v];
            if(!son[u]||size[son[u]]<size[v])son[u]=v;
        }
    }
    void dfs2(int u,int anc){
        pos[u]=++tot;idx[tot]=u;top[u]=anc;
        if(!son[u])return;
        dfs2(son[u],anc);
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(v==fa[u]||v==son[u])continue;
            dfs2(v,v);
        }
    }
    inline void init(){
        dep[1]=1;
        dfs1(1);
        dfs2(1,1);
    }
    int tr[N<<2];
    void build(int a,int l,int r){
        if(l==r){
            tr[a]=(is_square(idx[l]))? 0:1;
            return;
        }
        int mid=(l+r)>>1;
        build(a<<1,l,mid);build(a<<1|1,mid+1,r);
        tr[a]=tr[a<<1]+tr[a<<1|1];
    }
    inline int query(int a,int l,int r,int l1,int r1){
        if(r1<l||l1>r)return 0;
        if(l1<=l&&r<=r1)return tr[a];
        int mid=(l+r)>>1;
        return query(a<<1,l,mid,l1,r1)+query(a<<1|1,mid+1,r,l1,r1);
    }
    inline int qry(int x,int y){
        int ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            ans+=query(1,1,n+l,pos[top[x]],pos[x]);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])swap(x,y);
        return ans+query(1,1,n+l,pos[x],pos[y]);
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            g.add(u,v);g.add(v,u);
        }
        tarjan(1,0);
        init();build(1,1,n+l);
        int T=read();
        for(int i=1;i<=T;i++){
            int x=read(),y=read();
            printf("%d
    ",qry(x,y));
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    动态规划-重叠子问题
    百度 谷歌 Twitter,这么多短链接服务(Short Url)究竟哪家强?
    java中String初始化的两种方式
    bzoj 1218 [HNOI2003]激光炸弹
    Android TextView 横向滚动(跑马灯效果)
    混合高斯模型的EM求解(Mixtures of Gaussians)及Python实现源代码
    【Allwinner ClassA20类库分析】 2.free pascal语法及结构简析
    昂贵的聘礼
    C++11时间具体解释
    C++开发人脸性别识别教程(7)——搭建MFC框架之界面绘制
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12270220.html
Copyright © 2011-2022 走看看