Question:
Find the number of vertices that must pass through from one edge to another in the graph.
Ideas:
The first step must be through the cut point. Therefore, we can first connect the nodes and then contract the point to form a tree. The path on the tree is "non-cut point-not cut ". point-cut point -..." In this mode, the path U-> V only needs to find their LCA, and the answer can be calculated through (DIS [u] + dis [v]-Dis [LCA] * 2)/2.
Note:
This point is reduced by the edge, because it enables each edge to be in a connected block -- by wuyiqi
PS:
The scaled-down part of the Code draws on the SD. The code of the unintentional plug-in feels good to understand orz SD. the unintentional plug-in orz wuyiqi
Code:
#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<iostream>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<map>#include<set>#include<vector>using namespace std;typedef long long LL;#define N 20010#define M 400010#define inf 2147483647int n,m,q,tot,idx,top;int fu[M],fv[M];int head[N],dfn[N],low[N],belong[M],st[M],Tmp[N];int vis[N],dis[N],lca[N][20];struct edge{ int u,v,next; bool flag;}ed[M];pair<int,int> E[M];void init(){ tot=idx=top=0; memset(head,-1,sizeof(head)); memset(dfn,-1,sizeof(dfn)); memset(Tmp,0,sizeof(Tmp)); memset(vis,0,sizeof(vis));}void add(int u,int v){ ed[tot].u=u; ed[tot].v=v; ed[tot].flag=false; ed[tot].next=head[u]; head[u]=tot++;}void tarjan(int u,int fa){ int i,j,v; dfn[u]=low[u]=++idx; for(i=head[u];~i;i=ed[i].next) { v=ed[i].v; if(ed[i].flag||dfn[v]>=dfn[u]) continue; ed[i].flag=ed[i^1].flag=true; st[++top]=i; if(dfn[v]==-1) { tarjan(v,u); low[u]=min(low[u],low[v]); if(dfn[u]<=low[v]) { n++; do { j=st[top--]; if(Tmp[ed[j].v]!=n) { E[m++]=make_pair(n,ed[j].v); Tmp[ed[j].v]=n; } if(Tmp[ed[j^1].v]!=n) { E[m++]=make_pair(n,ed[j^1].v); Tmp[ed[j^1].v]=n; } belong[j>>1]=n; }while(j!=i); } } else low[u]=min(low[u],dfn[v]); }}void maketable(int u,int from){ int i,v; vis[u]=1; dis[u]=dis[from]+1; lca[u][0]=from; for(i=1;i<20;i++) lca[u][i]=lca[lca[u][i-1]][i-1]; for(i=head[u];~i;i=ed[i].next) { v=ed[i].v; if(v!=from&&!vis[v]) maketable(v,u); }}int findlca(int u,int v){ if(dis[v]>dis[u]) swap(u,v); int i,tmp=dis[u]-dis[v]; for(i=19;tmp;i--) { if(tmp>=(1<<i)) { tmp-=(1<<i); u=lca[u][i]; } } if(u==v) return u; for(i=19;i>=0;i--) { if(lca[u][i]!=lca[v][i]) { u=lca[u][i]; v=lca[v][i]; } } return lca[u][0];}int main(){ int i,j,u,v,f; while(~scanf("%d%d",&n,&m)) { if(!n&&!m) break; init(); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); fu[i]=u; fv[i]=v; } m=0; for(i=1;i<=n;i++) { if(dfn[i]==-1) tarjan(i,i); } tot=0; memset(head,-1,sizeof(head)); for(i=0;i<m;i++) { add(E[i].first,E[i].second); add(E[i].second,E[i].first); } for(i=1;i<=n;i++) { if(!vis[i]) maketable(i,0); } scanf("%d",&q); while(q--) { scanf("%d%d",&i,&j); u=belong[i-1]; v=belong[j-1]; f=findlca(u,v); printf("%d\n",(dis[u]+dis[v]-dis[f]*2)/2); } } return 0;}
Uvalive 4839 HDU 3686 traffic Real Time query system