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;
}

  

 

posted @ 2018-10-24 17:41  ~Silent  阅读(195)  评论(0编辑  收藏  举报
Live2D