P3128 [USACO15DEC]Max Flow P
题意
- 一颗树,树上每个结点初始化点权为0. 有k次操作,每次操作对路径<u, v>上每个结点都进行加1操作。问:k次操作全部完成后,点权值最大的结点的点权为多少?
思路
- 树上差分之点差分模板
- 无根树转有根树
- 对路径<u, v>操作时,++sum[u], ++sum[v], -- sum[lca(u, v)], --sum[fa[lca(u, v)]] 【即差分操作】
- dfs整棵树,某个结点的点权等于以该结点为根的子树上的差分和
- 边差分: ++sum[u], ++sum[v], sum[lca(u, v)] -= 2
- dfs跑完之后,sum[u]即为结点u到其父结点的边权
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int read()
{
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -f; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
const int maxN = 50004; //结点个数
int n, k;
struct EDGE{
int adj, to;
EDGE(int a = -1, int b = 0): adj(a), to(b) {}
}edge[maxN << 1];
int head[maxN], cnt;
void add_edge(int u, int v)
{
edge[cnt] = EDGE(head[u], v);
head[u] = cnt ++;
}
int f[maxN][20], deep[maxN];
void dfs(int u, int fa)
{
deep[u] = deep[fa] + 1;
f[u][0] = fa;
for(int i = head[u]; ~i; i = edge[i].adj)
{
int v = edge[i].to;
if(v == fa) continue;
dfs(v, u);
}
}
void pre()
{
dfs(1, 0);
for(int i = 1; i < 20; ++ i )
for(int j = 1; j <= n; ++ j )
f[j][i] = f[f[j][i - 1]][i - 1];
}
int LCA(int u, int v)
{
if(deep[u] < deep[v]) swap(u, v);
for(int i = 19; i >= 0; -- i )
{
if(deep[f[u][i]] >= deep[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 sum[maxN], ans;
void getAns(int u, int fa)
{
for(int i = head[u]; ~i; i = edge[i].adj)
{
int v = edge[i].to;
if(v == fa) continue;
getAns(v, u);
sum[u] += sum[v];
}
ans = max(ans, sum[u]);
}
int main()
{
memset(head, -1, sizeof(head));
n = read(); k = read();
for(int i = 0; i < n - 1; ++ i )
{
int u, v; u = read(); v = read();
add_edge(u, v);
add_edge(v, u);
}
pre();
for(int i = 0; i < k; ++ i )
{
int u, v; u = read(); v = read();
int lca = LCA(u, v), fa = f[lca][0];
++ sum[u]; ++ sum[v];
-- sum[lca]; -- sum[fa];
}
getAns(1, 0);
printf("%d\n", ans);
return 0;
}
QAQ,手瓢!把\n嫖成了\b....QAQ,所有样例全WA,亏我还找了半天bug 竟然没想到第一组测试样例是给出的样例QAQ