树的重心

int sz[N],mins = 1e9,rt;
void dfs(int u,int fa) {
	sz[u] = 1; int maxs = 0;
	for(int i = head[u]; i;i = e[i].nxt) {
		int v = e[i].v; if(v == fa) continue;
		dfs(v,u);
		sz[u] += sz[v];
		if(maxs < sz[v]) maxs = sz[v];
	}
	maxs = max(maxs,n-sz[u]);
	if(maxs < mins) mins = maxs,rt = u;
}

树的直径

  • 写法1

    我以前的写法

ll d[N],ans;
void dfs(int u,int fa) {
	ll maxd1 = 0,maxd2 = 0;
	for(int i = head[u]; i;i = e[i].nxt) {
		int v = e[i].v; if(v == fa) continue;
		dfs(v,u);
		ll tmp = d[u]+e[i].w;
		d[u] = max(d[u],tmp);
		if(tmp >= maxd1) maxd2 = maxd1,maxd1 = tmp;
		else if(tmp > maxd2) maxd2 = tmp;
	}
	ans = max(ans,maxd1+maxd2);
}
  • 写法2

    新看到的写法

ll d[N],ans;
void dfs(int u,int fa) {
	for(int i = head[u]; i;i = e[i].nxt) {
		int v = e[i].v; if(v == fa) continue;
		dfs(v,u);
		ans = max(ans,d[u]+d[v]+e[i].w);
		d[u] = max(d[u],d[v]+e[i].w);
	}
}

倍增求lca

void dfs(int u,int _fa) {
	dep[u] = dep[_fa]+1; fa[u][0] = _fa;
	for(int i = 1;i <= 19; ++i) fa[u][i] = fa[fa[u][i-1]][i-1];
	for(int i = head[u]; i;i = e[i].nxt) {if(e[i].v != _fa) dfs(e[i].v,u);}
}
int lca(int x,int y) {
	if(dep[x] < dep[y]) swap(x,y);
	for(int i = 19;i >= 0; --i) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	if(x == y) return x;
	for(int i = 19;i >= 0; --i) if(fa[x][i] != fa[y][i]) x = fa[x][i],y = fa[y][i];
	return fa[x][0];
}
posted @ 2019-09-18 20:42  陈星卿  阅读(124)  评论(0编辑  收藏  举报