P3128 [USACO15DEC] Max Flow P

发布时间 2023-09-25 16:28:50作者: 不o凡

P3128 [USACO15DEC] Max Flow P
有好几种解决方法,这里讲第一种树状数组 主要是线段树没调好
区间修改,单点查询,很明显我们可以用树状数组,简单又方便

树状数组
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
int n;
int read() {//快读
	char c = getchar(); int x = 0, f = 1;
	for (; c > '9' || c < '0'; c = getchar()) if (c == '-') f = -1;
	for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return x * f;
}
vector<int> g[N];//存图
//树链剖分模板
int dep[N], fa[N], sz[N], son[N];
void dfs1(int u, int father) {
	dep[u] = dep[father] + 1;
	sz[u] = 1; fa[u] = father;
	for (auto v : g[u]) {
		if (v == father) continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if (sz[son[u]] < sz[v]) son[u] = v;
	}
}
int cnt, id[N], top[N];
void dfs2(int u, int t) {
	top[u] = t; id[u] = ++cnt;
	if (!son[u]) return;
	dfs2(son[u], t);
	for (int v : g[u]) {
		if (v == son[u] || v == fa[u]) continue;
		dfs2(v, v);
	}
}
//树状数组模板
int a[N];
void add(int x,int k) {
	for (; x <= n; x += x & -x) {
		a[x] += k;
	}
}
int ask(int x) {
	int ans = 0;
	for (; x; x -= x & -x) {
		ans += a[x];
	}
	return ans;
}
void add_path(int u, int v) {
	while (top[v] != top[u]) {
		if (dep[top[u]] < dep[top[v]]) swap(u, v);//一定要注意是dep[top[u]],一开始写成dep[u],调试了半天
		add(id[top[u]],1),add(id[u]+1,-1);//利用差分思想
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) swap(v, u);
	add(id[v],1),add(id[u]+1,-1);
}


int main() {
	int m;
	n=read();m=read();
	for (int i = 1; i < n; i++) {
		int x=read(), y=read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	dfs1(1,0);
	dfs2(1, 1);
	while (m--) {
		int u=read(), v=read();
		add_path(u,v);
	}
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		ans = max(ans, ask(i));//寻找最大值
	}
	cout << ans;
	return 0;
}