啦啦啦,发个文纪念一下第一道在洛谷上A的黑题,一次性就过真是无比舒服~(虽然某些大佬说这题有点水……)题目其实思路不难,Tarjan缩点+LCA,不过因为是无向边,所以在Tarjan的时候做点标记就行了,不过第四个点会被卡,用vector存边就可以A掉了。另外输出用二进制这个应该没什么好说的。
下面放代码:
#include<cmath> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int N=10001; const int M=50001; int n,m,T,indexx,id,dep[N]; int low[N],dfn[N],size[N]; int f[N][21],belong[N]; bool vis[N]; vector<int>edge[M<<1]; vector<int>node[M<<1]; stack<int>team; inline int read() { char ch=getchar();int num=0;bool flag=false; while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)flag=true;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){num=num*10+ch-‘0‘;ch=getchar();} return flag?-num:num; } inline int Min(int x,int y) {return x<y?x:y;} inline void tarjan(int u,int last) { dfn[u]=low[u]=++indexx; vis[u]=true;team.push(u); for(int i=0;i<node[u].size();i++){ int v=node[u][i]; if(v==last)continue; if(!dfn[v]){ tarjan(v,u); low[u]=Min(low[u],low[v]);} else if(vis[v]) low[u]=Min(low[u],dfn[v]); } if(dfn[u]==low[u]){ int v;++id; do{ v=team.top();team.pop(); vis[v]=false; belong[v]=id;size[id]++; }while(v!=u); } } void build() { for(int i=1;i<=n;i++) for(int j=0;j<node[i].size();j++){ int v=node[i][j]; if(belong[i]!=belong[v]) edge[belong[i]].push_back(belong[v]); } } inline void dfs(int u,int fa,int depth) { dep[u]=depth;f[u][0]=fa; for(int i=0;i<edge[u].size();i++) if(edge[u][i]!=fa) dfs(edge[u][i],u,depth+1); } void init() { for(int j=1;j<=20;j++) for(int i=1;i<=id;i++) f[i][j]=f[f[i][j-1]][j-1]; } inline int LCA(int a,int b) { if(dep[a]<dep[b])swap(a,b); for(int i=20;i>=0;i--) if(dep[f[a][i]]>=dep[b]) a=f[a][i]; if(a==b)return a; for(int i=20;i>=0;i--) if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; return f[a][0]; } inline void print(int x) { if(x==0)return; print(x>>1); putchar(x%2+‘0‘); } int main() { n=read();m=read(); for(int i=1;i<=m;i++){ int x=read();int y=read(); node[x].push_back(y); node[y].push_back(x);} for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i,0); build();dfs(1,0,0);init(); T=read(); for(int i=1;i<=T;i++){ int x=read();int y=read(); x=belong[x],y=belong[y]; int lca=LCA(x,y); print((dep[x]+dep[y])-(dep[lca]<<1)+1); printf("\n"); } return 0; }