• 压力


    首先如果路径上有割点一定是必经点,然后如果是环上的点(除了割点)一定有多条路径可以到,所以环上(除了割点起点终点)都不必经。

    所以点双缩点,重新建图(普通建图or圆方)

    那么对于每组询问lca加普通树差标记一下,

    对于每组询问拿数组zz记录起点终点,

    最后dfs扫一遍

    ,结束时如果不为割点,直接输出zz

    否则输出dfs扫出的ans

    必经点模版题

    #include<bits/stdc++.h>
    #define ll long long
    #define pt printf("******
    ")
    #define A 1000000
    using namespace std;
    ll tot=0,head[A],sta[A],low[A],dfn[A],nxt[A],ver[A],deep[A],belong[A],cut[A];
    ll tc=0,head_c[A],nxt_c[A],ver_c[A],sz[A],f[A][30],ans[A],zz[A];
    ll n,m,q,t,num=0,cnt=0,root,top=0;
    vector<ll> scc[A];
    bool flag[A],vis[A];
    void add(ll x,ll y){
        nxt[++tot]=head[x],head[x]=tot,ver[tot]=y;
    }
    void add_c(ll x,ll y){
        nxt_c[++tc]=head_c[x],head_c[x]=tc,ver_c[tc]=y;
    }
    void tarjan(ll x){
        low[x]=dfn[x]=++num;
        sta[++top]=x;ll vis=0;
        if(x==root&&!head[x])
        {
            cnt++;
            belong[x]=cnt;
            scc[cnt].push_back(x);
        }
        for(ll i=head[x];i;i=nxt[i]){
            ll y=ver[i];
            if(!dfn[y]){
                tarjan(y);
                low[x]=min(low[x],low[y]);
                if(dfn[x]<=low[y]){
                    vis++;
                    if(x!=root||vis>1) cut[x]=1;
                    cnt++;
                    ll z;
                    do{
                        z=sta[top--];
                        belong[z]=cnt;
                        scc[cnt].push_back(z);
                    }while(z!=y);
                    belong[x]=cnt;
                    scc[cnt].push_back(x);
                }
            }
            else low[x]=min(low[x],dfn[y]);
        }
    }
    inline ll lca(ll x,ll y){
        if(deep[x]>deep[y]) swap(x,y);
        ll w;
        for(w=0;(1<<w)<=deep[y];w++);
        w--;
        for(ll i=w;i>=0;i--)
        {
    //        printf("deep[%lld]=%lld deep[%lld]=%lld f[%lld]=%lld
    ",x,deep[x],y,deep[y],i,f[y][i]);
            
            if(deep[x]<=deep[f[y][i]]) y=f[y][i];
            if(deep[x]==deep[y]) break;
        }
        if(x==y) return x;
        for(ll i=w;i>=0;i--){
            if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        }
        return f[y][0];
    }
    void dfs2(ll x,ll de){
        deep[x]=de;flag[x]=1;
        for(ll i=head_c[x];i;i=nxt_c[i]){
            ll y=ver_c[i];
            if(flag[y])
                continue;
            f[y][0]=x;
            dfs2(y,de+1);
        }
    }
    ll dfs3(ll x){
        vis[x]=1;
        for(ll i=head_c[x];i;i=nxt_c[i]){
            ll y=ver_c[i];
            if(vis[y]) continue;
            ll to=dfs3(y);
            ans[x]+=to;
        }
        return ans[x];
    }
    int main(){
    //    freopen("mkd.txt","r",stdin);
    //    freopen("wa.txt","w",stdout);
        scanf("%lld%lld%lld",&n,&m,&q);
        t=log(n)/log(2)+5;
        for(ll i=1;i<=m;i++){
            ll x,y;
            scanf("%lld%lld",&x,&y);
            add(x,y);add(y,x);
        }
        for(ll i=1;i<=n;i++){
            if(!dfn[i]) root=i,tarjan(i);
        }
        num=cnt;
        for(ll i=1;i<=n;i++)
        if(cut[i]) belong[i]=++num/*,printf("gd=%lld
    ",i)*/;
        for(ll i=1;i<=cnt;i++){
            ll size=scc[i].size();
            for(ll j=0;j<size;j++){
                if(cut[scc[i][j]]){
                    add_c(i,belong[scc[i][j]]);
                    add_c(belong[scc[i][j]],i);
                }
            }
        }
        dfs2(1,1),f[1][0]=1;
        for(ll j=1;j<=t;j++)
            for(ll i=1;i<=num;i++)
                f[i][j]=f[f[i][j-1]][j-1];
        /*for(ll i=1;i<=n;i++){
            printf("belong=%lld
    ",belong[i]);    
        }
        for(ll i=1;i<=num;i++)
        {
            printf("deep[i]=%lld f[i][0]=%lld belong=%lld
    ",deep[belong[i]],f[belong[i]][0],belong[i]);
        }*/
        for(ll i=1;i<=q;i++){
            ll x,y;
            scanf("%lld%lld",&x,&y);
            ll lc=lca(belong[x],belong[y]);
    //        cout<<lc<<endl;
            zz[x]++,zz[y]++;
    //        printf("x=%lld y=%lld lc=%lld lf=%lld
    ",belong[x],belong[y],lc,f[lc][0]);
            ans[belong[x]]++;
            ans[belong[y]]++;
            ans[lc]--;
            if(f[lc][0]!=lc)ans[f[lc][0]]--;
        }
        dfs3(1);
        for(ll i=1;i<=n;i++){
            if(cut[i]) cout<<ans[belong[i]]<<endl;
            else cout<<zz[i]<<endl;
        }
        return 0;
    }
    View Code
    我已没有下降的余地
  • 相关阅读:
    JS框架设计读书笔记之-选择器引擎02
    JS框架设计读书笔记之-选择器引擎01
    JS框架设计读书笔记之-小知识
    JS框架设计读书笔记之-函数
    JS框架设计读书笔记之-核心模块
    7.19 NOIP模拟6
    一 网络基础之网络协议篇
    Socket 网络编程
    Python 常用模块
    类的特殊成员
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11191540.html
Copyright © 2020-2023  润新知