社区讨论

求调

学术版参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@m5t6jpb0
此快照首次捕获于
2025/01/12 13:33
去年
此快照最后确认于
2025/11/04 11:43
4 个月前
查看原帖
P4606MLE 0pts求调,能过样例,把树剖求LCA改成倍增求LCA就AC了,但不知道我的树剖求LCA哪里写错了
CPP
#include<bits/stdc++.h>
using namespace std;
int n,m,k,t,cnt,dfn[200005],low[100005],st[100005],top,cnt2,x,y,ans,s[200005],ss[100005],dep[200005],f[200005],son[200005],tp[200005],dis[200005];
vector<int> v1[100005],v2[200005];
void tarjan(int u) {
    low[u]=dfn[u]=++cnt;
    st[++top]=u;

    for (auto v:v1[u]) {
        if (!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u], low[v]);
            if (low[v]==dfn[u]) {
                ++cnt2;
                int x=0;
                while(x!=v){
                    x=st[top];
                    v2[cnt2].push_back(x);
                    v2[x].push_back(cnt2);
                    top--;
                }
                v2[cnt2].push_back(u);
                v2[u].push_back(cnt2);
            }
        }   
        else low[u]=min(low[u],dfn[v]);
    }
}




void dfs1(int u,int fa){
    f[u]=fa;
    dep[u]=dep[fa]+1;
    dis[u]=dis[fa];
    dfn[u]=++cnt;
    if(u<=n) dis[u]++;
    s[u]=1;
    int mson=-1;
    for(auto v:v2[u]){
        if(v==fa) continue;
        dfs1(v,u);
        s[u]+=s[v];
        if(s[v]>mson){
            mson=s[v];
            son[u]=v;
        }
    
    }

}
void dfs2(int u,int fa){
    tp[u]=fa;
    if(son[u]==0) return ;
    dfs2(son[u],fa);
    for(auto v:v2[u]){
        if(v==f[u]||v==son[u]) continue;  
        dfs2(v,v);
    }
}

int lca(int x,int y){
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
        x=f[tp[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    return x;
}

int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) {v1[i].clear();dfn[i]=low[i]=0;}
        for(int i=1;i<=2*n;i++){
            v2[i].clear();
        }
   
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            v1[x].push_back(y);
            v1[y].push_back(x);

        }
        cnt=0;
        top=0;
        cnt2=n;
        tarjan(1);
        top--;
        cnt=0;
        dfs1(1,0);
        dfs2(1,1);

        scanf("%d",&k);
        for(int i=1;i<=k;i++){
            ans=0;
            scanf("%d",&x);
            for(int j=1;j<=x;j++){
                scanf("%d",&ss[j]);
            }
  
            sort(ss+1,ss+x+1,[](int a,int b) { return dfn[a]<dfn[b];});
            for (int j=1;j<=x;j++){
                int u=ss[j],v=ss[j%x+1];
                ans+=dis[u]+dis[v]-2*dis[lca(u,v)];
                //cout<<u<<" "<<dis[u]<<" "<<dis[v]<<" ";
            }
      
            if (lca(ss[1], ss[x])<=n) ans+=2;
            ans-=x*2;
            ans/=2;
            printf("%d\n",ans);
        }



    }


    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...