萌新刚学OI求助(点双+LCA)
查看原帖
萌新刚学OI求助(点双+LCA)
328995
_Famiglistimo楼主2021/5/3 22:47

RT,堪堪过了样例,交上去爆零

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+5;
const int M = 1e5+5;

struct Side{int from,to;}side[M<<1];
struct Edge{int nex,to;}edge[M<<1],EDGE[M<<1];
int head[N],HEAD[N],dfn[N],low[N],v_dcc[N];
int stk[N],id[N],dep[N],f[N][25];
int elen,ELEN,n,m,q,s,t,top,cnt,tim,root;
vector<int>dcc[N];
bool cut[N];

void init(){
    elen=ELEN=tim=cnt=top=0;
    memset(head,0,sizeof(head));
    memset(HEAD,0,sizeof(HEAD));
    memset(dfn,0,sizeof(dfn));
    memset(id,0,sizeof(id));
    memset(cut,0,sizeof(cut));
}
void addedge(int from,int to){
    edge[++elen]={head[from],to};
    head[from]=elen;
}
void ADDEDGE(int FROM,int TO){
    EDGE[++ELEN]={HEAD[FROM],TO};
    HEAD[FROM]=ELEN;
}
void tarjan(int u){
    int child=0;
    dfn[u]=low[u]=++tim;stk[++top]=u;
    if(!head[u]&&u==root){
        dcc[++cnt].clear();
        dcc[cnt].push_back(u);
        return ;
    }
    for(int e=head[u];e;e=edge[e].nex){
        int v=edge[e].to;
        if(!dfn[v]){
            tarjan(v);low[u]=min(low[u],low[v]);
            if(dfn[u]<=low[v]){
                if(u!=root||++child>=2)cut[u]=true;
                dcc[++cnt].clear();
                int w;
                do{
                    w=stk[top--];
                    dcc[cnt].push_back(w);
                }while(w!=v);
                dcc[cnt].push_back(u);
            }
        }else low[u]=min(low[u],dfn[v]);
    }
}
void dfs(int u,int fath){
    dep[u]=dep[fath]+1;f[u][0]=fath;
    for(int i=1;i<=23;i++)f[u][i]=f[f[u][i-1]][i-1];
    for(int e=HEAD[u];e;e=EDGE[e].nex){
        int v=EDGE[e].to;
        if(!dep[v])dfs(v,u);
    }
}
int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    for(int i=23;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
    if(x==y)return x;
    for(int i=23;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
    return f[x][0];
}
int calc(int x,int y){
    x=v_dcc[x];y=v_dcc[y];int l=lca(x,y);
    return (dep[x]+dep[y]-dep[l]*2)/2;
}

int main(){
    while(scanf("%d%d",&n,&m)&&(n||m)){
        init();
        for(int i=1,u,v;i<=m;i++){
            scanf("%d%d",&u,&v);
            addedge(u,v);addedge(v,u);
            side[i]={u,v};
        }
        for(int i=1;i<=n;i++) 
            if(!dfn[i])root=i,tarjan(i);
        tim=cnt;
        for(int i=1;i<=n;i++)
            if(cut[i])id[i]=++tim;
        for(int i=1;i<=cnt;i++){
            for(int j=0;j<(int)dcc[i].size();j++){
                int x=dcc[i][j];
                if(cut[x])ADDEDGE(i,id[x]),ADDEDGE(id[x],i);
                v_dcc[x]=i;
            }
        }
        for(int i=1;i<=tim;i++)
            if(!dep[i])dfs(i,0);
        scanf("%d",&q);
        while(q--){
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d\n",max(
                max(calc(side[a].to,side[b].from),calc(side[a].to,side[b].to)),
                max(calc(side[a].from,side[b].from),calc(side[a].from,side[b].to)))
            );                            
        }
    }
    return 0;
}

码风丑,轻喷

2021/5/3 22:47
加载中...