BZOJ 3331: [BeiJing2013]压力
圆方树
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,q,Num,cnt,Cnt,top,ti,stack[100005],instack[100005],dfn[100005],low[100005],Dep[200005],Last[200005],F[200005][19],last[100005],sz[200005];
struct node{
int to,next;
}e[400005],E[400005];
void add(int a,int b){
e[++cnt].to=b;
e[cnt].next=last[a];
last[a]=cnt;
}
void ADD(int a,int b){
E[++Cnt].to=b;
E[Cnt].next=Last[a];
Last[a]=Cnt;
}
void Tarjan(int x,int fa){
dfn[x]=low[x]=++ti;
stack[++top]=x;
for (int i=last[x]; i; i=e[i].next){
int V=e[i].to;
if (!dfn[V]){
Tarjan(V,x);
low[x]=min(low[x],low[V]);
if (low[V]>=dfn[x]){
ADD(++Num,x),ADD(x,Num);
int u=-1;
while (u!=V){
u=stack[top--];
ADD(Num,u),ADD(u,Num);
}
}
}
else low[x]=min(low[x],dfn[V]);
}
}
void dfs(int x,int fa,int dep){
F[x][0]=fa,Dep[x]=dep;
for (int i=1; i<19; i++) F[x][i]=F[F[x][i-1]][i-1];
for (int i=Last[x]; i; i=E[i].next){
int V=E[i].to;
if (V==fa) continue;
dfs(V,x,dep+1);
}
}
int lca(int x,int y){
if (Dep[x]<Dep[y]) swap(x,y);
for (int i=18; i>=0; i--) if (Dep[F[x][i]]>=Dep[y]) x=F[x][i];
if (x==y) return x;
for (int i=17; i>=0; i--) if (F[x][i]!=F[y][i]) x=F[x][i],y=F[y][i];
return F[x][0];
}
void solve(int x,int fa){
for (int i=Last[x]; i; i=E[i].next){
int V=E[i].to;
if (V==fa) continue;
solve(V,x);
sz[x]+=sz[V];
}
}
int main(){
scanf("%d%d%d",&n,&m,&q);
for (int i=1; i<=m; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
Num=n;
Tarjan(1,0);
dfs(1,0,1);
while (q--){
int x,y;
scanf("%d%d",&x,&y);
int LCA=lca(x,y);
sz[x]++,sz[y]++,sz[LCA]--,sz[F[LCA][0]]--;
}
solve(1,0);
for (int i=1; i<=n; i++) printf("%d\n",sz[i]);
return 0;
}

浙公网安备 33010602011771号