【圆方树】BZOJ3331 压力

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34454069/article/details/88790113

题目:

在这里插入图片描述

分析:

圆方树板子题

建出圆方树后,直接树上差分即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 400010
using namespace std;
struct node{
	int u,v;
	node () {}
	node (int u1,int v1):u(u1),v(v1) {}	
}Edge[MAXN];
vector<int> a[MAXN];
int dfn[MAXN],low[MAXN],cnt;
int stk[MAXN],tp,n2,ncnt;
void dfs(int x,int fa=0){
	dfn[x]=low[x]=++cnt;
	stk[++tp]=x;
	int flg=0;
	for(int i=0;i<int(a[x].size());i++){
		int u=a[x][i];
		if(u==fa){
			flg++;
			if(flg==1)
				continue;
		}
		if(dfn[u]==0){
			dfs(u,x);
			low[x]=min(low[x],low[u]);
			if(low[u]>=dfn[x]){
				n2++;
				Edge[++ncnt]=node(n2,x);
				while(1){
					Edge[++ncnt]=node(stk[tp],n2);
					if(stk[tp--]==u)
						break;
				}
			}
		}
		else
			low[x]=min(low[x],dfn[u]);
	}	
}
int f[MAXN][20];
int dep[MAXN];
void prepare(int x,int fa=0){
	f[x][0]=fa;
	dep[x]=dep[fa]+1;
	for(int i=1;i<20;i++)
		f[x][i]=f[f[x][i-1]][i-1];
	for(int i=0;i<int(a[x].size());i++){
		int u=a[x][i];
		if(u==fa)
			continue;
		prepare(u,x);	
	}
}
int lca(int u,int v){
	if(dep[u]<dep[v])
		swap(u,v);
	for(int i=19;i>=0;i--)
		if(dep[f[u][i]]>=dep[v])
			u=f[u][i];
	if(u==v)
		return u;
	for(int i=19;i>=0;i--)
		if(f[u][i]!=f[v][i]){
			u=f[u][i];
			v=f[v][i];	
		}
	return f[u][0];
}
int add[MAXN];
void get_ans(int x,int fa=0){
	for(int i=0;i<int(a[x].size());i++){
		int u=a[x][i];
		if(u==fa)
			continue;
		get_ans(u,x);
		add[x]+=add[u];
	}
}
int main(){
	int n,m,q,u,v;
	SF("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;i++){
		SF("%d%d",&u,&v);
		a[u].push_back(v);	
		a[v].push_back(u);
	}
	n2=n;
	dfs(1);
	for(int i=1;i<=n;i++)
		a[i].clear();
	for(int i=1;i<=ncnt;i++){
		a[Edge[i].u].push_back(Edge[i].v);
		a[Edge[i].v].push_back(Edge[i].u);	
	}
//	for(int i=1;i<=ncnt;i++)
//		PF("[%d %d]\n",Edge[i].u,Edge[i].v);
	prepare(1);
	while(q--){
		SF("%d%d",&u,&v);
		add[u]++,add[v]++;
		int x=lca(u,v);
		add[x]--;
		add[f[x][0]]--;
	}
	get_ans(1);
	for(int i=1;i<=n;i++)
		PF("%d\n",add[i]);
}

猜你喜欢

转载自blog.csdn.net/qq_34454069/article/details/88790113