zoukankan      html  css  js  c++  java
  • 洛谷P5236 圆方树模板题

    狭义的圆方树   洛谷P5236 圆方树模板题

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+10;
    struct node{
        int nxt,w,to;
    }e[N],E[N];
    int head[N],Head[N],cnt,Cnt;
    int fa[N],deep[N],top[N],son[N],siz[N],S[N],dis[N];
    int n,m,q,An,Bn;
    int sum[N];
    int dfn[N],low[N],tot;
    void add(int from,int to,int w){
        e[++cnt].nxt=head[from];
        e[cnt].w=w;
        e[cnt].to=to;
        head[from]=cnt;
    }
    void Add(int from,int to,int w){
        E[++Cnt].nxt=Head[from];
        E[Cnt].w=w;
        E[Cnt].to=to;
        Head[from]=Cnt;
    }
    void dfs1(int from,int Fa,int dep){
        fa[from]=Fa;
        deep[from]=dep;
        siz[from]=1;
        son[from]=0;
        int maxson=0;
        for(int i=Head[from];i;i=E[i].nxt){
            int to=E[i].to;
            if(to==Fa)continue;
            dis[to]=dis[from]+E[i].w;
            dfs1(to,from,dep+1);
            siz[from]+=siz[to];
            if(maxson<siz[to]){
                maxson=siz[to];
                son[from]=to;
            }
        }
    }
    void dfs2(int from,int topf){
        top[from]=topf;
        if(!son[from])return;
        dfs2(son[from],topf);
        for(int i=Head[from];i;i=E[i].nxt){
            int to=E[i].to;
            if(to==son[from]||to==fa[from])continue;
            dfs2(to,to);
        }
    }
    int lca(int x,int y){
        while(top[x]!=top[y]){
            if(deep[top[x]]<deep[top[y]])swap(x,y);
            x=fa[top[x]];
        }
        if(deep[x]>deep[y])swap(x,y);
        return x;
    }
    int find(int P,int x){
        int res=x;
        while(top[x]!=top[P]){
            res=top[x];
            x=fa[top[x]];
        }
        if(P==x)return res;
        else return son[P];
    }
    void build(int from,int to,int w){
        ++Bn;
        int now=to,res=w;
        while(now!=fa[from]){
            sum[now]=res;
            res+=S[now];
            now=fa[now];
        }
        sum[Bn]=sum[from];
        sum[from]=0;
        now=to;
        while(now!=fa[from]){
            int Bw=min(sum[now],sum[Bn]-sum[now]);
            Add(now,Bn,Bw);
            Add(Bn,now,Bw);
            now=fa[now];
        }
        return;
    }
    void tarjan(int from,int Fa){
        dfn[from]=low[from]=++tot;
        for(int i=head[from];i;i=e[i].nxt){
            int to=e[i].to;
            int w=e[i].w;
            if(to==Fa)continue;
            if(!dfn[to]){
                fa[to]=from;
                S[to]=w;
                tarjan(to,from);
                low[from]=min(low[from],low[to]);
            }else{
                low[from]=min(low[from],dfn[to]);
            }
            if(low[to]<=dfn[from])continue;
            Add(from,to,w);
            Add(to,from,w);
        }
        for(int i=head[from];i;i=e[i].nxt){
            int to=e[i].to;
            int w=e[i].w;
            if(fa[to]==from||dfn[to]<dfn[from])continue;
            build(from,to,w);
        }
        return;
    }
    int main(){
        scanf("%d%d%d",&An,&m,&q);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        Bn=An;
        tarjan(1,0);
        dfs1(1,0,1);
        dfs2(1,1);
        for(int i=1;i<=q;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            int L=lca(x,y);
            if(L<=An){
                int ans=dis[y]+dis[x]-2*dis[L];
                printf("%d
    ",ans);
            }else{
                int X=find(L,x);
                int Y=find(L,y);
                int ans=min(abs(sum[X]-sum[Y]),sum[L]-abs(sum[X]-sum[Y]));
                ans+=dis[x]-dis[X]+dis[y]-dis[Y];
                printf("%d
    ",ans);
            }
        }
    }
    rst

    广义的圆方树 洛谷P4630 广义圆方树模板题

    #include<bits/stdc++.h>
    using namespace std;
    const int N=500010;
    struct node{
        int nxt,to;
    }e[N],E[N];
    int head[N],Head[N];
    int cnt,Cnt,tot,num;
    int dfn[N],low[N],stk[N],tp,sum[N],siz[N];
    long long ans;
    int n,Bn,m;
    void add(int from,int to){
        e[++cnt].nxt=head[from];
        e[cnt].to=to;
        head[from]=cnt;
    }
    void Add(int from,int to){
        E[++Cnt].nxt=Head[from];
        E[Cnt].to=to;
        Head[from]=Cnt;
    }
    void tarjan(int from){
        dfn[from]=low[from]=++tot;
        stk[++tp]=from;
        num++;
        for(int i=head[from];i;i=e[i].nxt){
            int to=e[i].to;
            if(!dfn[to]){
                tarjan(to);
                low[from]=min(low[from],low[to]);
                if(low[to]==dfn[from]){
                    sum[++Bn]=0;
                    while(stk[tp+1]!=to){
                        Add(stk[tp],Bn);
                        Add(Bn,stk[tp]);
                        sum[Bn]++;
                        tp--;
                    }
                    Add(from,Bn);
                    Add(Bn,from);
                    sum[Bn]++;
                }
            }else {
                low[from]=min(low[from],dfn[to]);
            }
        }
    }
    void dfs(int from,int F){
        if(from<=n)siz[from]=1;
        for(int i=Head[from];i;i=E[i].nxt){
            int to=E[i].to;
            if(to==F)continue;
            dfs(to,from);
            ans+=(long long)2*sum[from]*siz[from]*siz[to];
            siz[from]+=siz[to];
        }
        ans+=(long long)2*sum[from]*siz[from]*(num-siz[from]);
    }
    int main(){
        scanf("%d%d",&n,&m);
        Bn=n;
        for(int i=1;i<=n;i++)sum[i]=-1;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i]){
                num=0;
                tarjan(i);
                tp--;
                dfs(i,0);
            }
        }
        printf("%lld
    ",ans);
    }
    rst
  • 相关阅读:
    Jasper 常用知识点总结
    Linux
    搭建spring项目,无法创建RequestMappingHandlerMapping异常
    pom.xml文件设置
    MySQL的常用JSON函数
    SQL中的条件判断语句(case when zhen if,ifnull)用法
    sql查询原理
    sql积累
    Linux常用命令大全
    mysql中group by 的用法解析
  • 原文地址:https://www.cnblogs.com/passione-123456/p/12248949.html
Copyright © 2011-2022 走看看