题解 UVA1464 【Traffic Real Time Query System】 点双缩点+LCA
UVA1464 Traffic Real Time Query System
我终于AC了呜呜呜
题面
一个城市有
题解
- 点双缩点
缩点之后建新图,会发现图一定是
连通块---割顶---连通块---……---连通块
所以答案就是
感性理解一下
注意点
-
- 题目保证从
road_S 到road_T 一定有路,但图不一定连通,缩点之后有多个树,不只有一颗树
给个代码对照一下吧,调代码没有一个参照好累好累
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define re register
#define il inline
#define ll long long
using namespace std;
il int read(){
int s=0,f=0;char c=getchar();
while(c<'0'||c>'9') f=(c=='-'),c=getchar();
while(c>='0'&&c<='9') s=(s<<3)+(s<<1)+(c^'0'),c=getchar();
return f?-s:s;
}
const int N=2e4+5,M=1e5+5;
int n,m,q;
struct E{
int next,to;
bool fl;
};
int dfn[N],low[N],dfs_tim,st[N],top,dccnum,cut[N],cutnum,ebelong[M]; //点双
struct G{
E e[M<<1];
int head[N],cnt;
il void add_edge(int u,int v){
e[cnt].next=head[u],e[cnt].to=v,head[u]=cnt++;
}
il void init(){
while(cnt) e[cnt].fl=0,cnt--;
e[0].fl=0;
memset(head,-1,sizeof(head));
}
}g,g2;
void tarjan(int u,int rt){
dfn[u]=low[u]=++dfs_tim;
int son=0;
for(re int i=g.head[u];~i;i=g.e[i].next){
int v=g.e[i].to;
if(g.e[i].fl) continue;
g.e[i].fl=g.e[i^1].fl=1;
st[++top]=(i>>1);
if(!dfn[v]){
son++;
tarjan(v,rt);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
if(u!=rt) cut[u]=1;
++dccnum;
while(1){
int x=st[top];
ebelong[x]=dccnum;
top--;
if(x==(i>>1)) break;
}
}
}
else low[u]=min(low[u],dfn[v]);
}
if(u==rt&&son>=2) cut[u]=1;
}
int f[N][16],dep[N],lg2[N];
int vis[N],tot;
void dfs(int u,int fa){
vis[u]=tot;
dep[u]=dep[fa]+1;
f[u][0]=fa;
for(re int i=1;(1<<i)<=dep[u];++i)
if(f[u][i-1]) f[u][i]=f[f[u][i-1]][i-1];
for(re int i=g2.head[u];~i;i=g2.e[i].next){
int v=g2.e[i].to;
if(v!=fa) dfs(v,u);
}
}
il int LCA(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y])
x=f[x][lg2[dep[x]-dep[y]]];
if(x==y) return x;
for(re int i=lg2[dep[x]];i>=0;--i)
if(f[x][i]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
int main(){
while(scanf("%d%d",&n,&m),n){
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
memset(cut,0,sizeof(cut));
memset(f,0,sizeof(f));
memset(ebelong,0,sizeof(ebelong));
dfs_tim=dccnum=top=tot=cutnum=0;
g.init(),g2.init();
for(re int i=1,u,v;i<=m;++i) u=read(),v=read(),g.add_edge(u,v),g.add_edge(v,u);
for(re int i=1;i<=n;++i)
if(!dfn[i]) tarjan(i,i);
for(re int u=1;u<=n;++u) if(cut[u]){
cut[u]=(++cutnum)+dccnum;
++tot;
for(re int i=g.head[u];~i;i=g.e[i].next){
int v=ebelong[i>>1];
if(vis[v]!=tot) vis[v]=tot,g2.add_edge(v,cut[u]),g2.add_edge(cut[u],v);
}
}
lg2[0]=-1;
for(re int i=1;i<=dccnum+cutnum;++i) lg2[i]=lg2[i>>1]+1;
++tot;dep[0]=-1;
for(re int i=1;i<=dccnum+cutnum;++i) if(vis[i]!=tot) dfs(i,0);
q=read();
for(re int i=1,u,v;i<=q;++i)
u=ebelong[read()-1],v=ebelong[read()-1],
printf("%d\n",(dep[u]+dep[v]-2*dep[LCA(u,v)]+1)/2);
}
return 0;
}