专栏文章

P3128 Max Flow P lca 差分

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqadsx1
此快照首次捕获于
2025/12/04 01:34
3 个月前
此快照最后确认于
2025/12/04 01:34
3 个月前
查看原文
算法竞赛上有讲解
差分将对区间操作转换为对点操作,降低复杂度
想的时候以为算前缀和是从根往下算,这样就不能充分利用上差分,卡了一会
100pts:
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,s,ans;
int head[N],nxt[N],to[N],cnt;
int deep[N],fa[N][25];
int d[N],r[N];
void add(int u,int v){
	nxt[++cnt]=head[u];
	head[u]=cnt;
	to[cnt]=v;
	return ;
}
void dfs(int x,int father){
	deep[x]=deep[father]+1;
	fa[x][0]=father;
	for(int i=1;(1<<i)<=deep[x];i++)	fa[x][i]=fa[fa[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])	if(to[i]!=father) dfs(to[i],x);
}
int lca(int x,int y){
	if(deep[x]<deep[y]) swap(x,y);
	for(int i=24;i>=0;i--)	if(deep[x]-(1<<i)>=deep[y]) x=fa[x][i];
	if(x==y) return x;
	for(int i=24;i>=0;i--)	if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
	return fa[x][0];
}
void dfs0(int x,int father){
	r[x]=d[x];
	for(int i=head[x];i;i=nxt[i]){
		if(to[i]!=father){
			dfs0(to[i],x);
			r[x]+=r[to[i]];
		}
		if(r[x]>ans) ans=r[x];
	}
	return ;
}
int main(){
	scanf("%d%d",&n,&m);
	int a,b;
	for(int i=1;i<n;i++){
		scanf("%d%d",&a,&b);
		add(a,b),add(b,a);
	}	
	dfs(1,0);
	for(int i=1,Lca;i<=m;i++){
		scanf("%d%d",&a,&b);
		Lca=lca(a,b);
		
		d[a]++,d[b]++;
		d[Lca]--,d[fa[Lca][0]]--;
		
	}
	dfs0(1,0);
	printf("%d",ans);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...