树上差分——点差分裸题 P3128 [USACO15DEC]最大流Max Flow

本文详细介绍了树形动态规划(Tree DP)和最近公共祖先(LCA)算法的实现细节,通过具体代码展示了如何在树状结构中进行状态传递与查询优化,适用于解决涉及树结构的复杂问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

讲解:

https://rpdreamer.blog.luogu.org/ci-fen-and-shu-shang-ci-fen

 

 1 #include <bits/stdc++.h>
 2 #define read read()
 3 #define up(i,l,r) for(register int i = (l);i <= (r);i++)
 4 #define down(i,l,r) for(register int i = (l);i >= (r);i--)
 5 #define traversal_vedge(i) for(register int i = head[u]; i ;i = e[i].nxt)
 6 #define ll long long
 7 using namespace std;
 8 int read
 9 {
10     int x = 0, f = 1; char ch = getchar();
11     while(ch < 48 || ch > 57) {if(ch == '-')f = -1; ch = getchar();}
12     while(ch >=48 && ch <=57) {x = 10 * x + ch - 48;ch = getchar();}
13     return x * f; 
14 }
15 //--------------------------------------------------------------------
16 const int N = 50005;
17 int n,k;
18 struct edge{
19     int v,nxt;
20 }e[N<<1]; int tot,head[N];
21 void add(int u,int v) {e[++tot] = (edge){v,head[u]};head[u] = tot;}
22 
23 int dep[N],size[N],fa[N],top[N];
24 int cnt[N],maxp = 0;
25 
26 void dfs(int u)
27 {
28     dep[u] = dep[fa[u]]+1;
29     size[u] = 1;
30     top[u] = u;
31     int hson_id = 0,hson_size = 0;
32     traversal_vedge(i)
33     {
34         int v = e[i].v;
35         if(v == fa[u]) continue;
36         fa[v] = u;
37         dfs(v);
38         size[u] += size[v];
39         if(size[v] > hson_size) hson_id = v,hson_size = size[v];
40     }
41     if(hson_id) top[hson_id] = u;
42 }
43 
44 int find(int u)
45 {
46     if(top[u] == u) return u;
47     top[u] = find(top[u]);
48     return top[u];
49 }
50 
51 int lca(int x,int y)
52 {
53     if(find(x) != find(y))
54     {
55         if(dep[top[x]] > dep[top[y]]) return lca(fa[top[x]],y);
56         else return lca(x,fa[top[y]]);
57     }
58     return dep[x] > dep[y] ? y : x;
59 }
60 
61 void dfs_tree(int u)
62 {
63     traversal_vedge(i)
64     {
65         int v = e[i].v;
66         if(v == fa[u]) continue;
67         dfs_tree(v);
68         cnt[u] += cnt[v];
69     }
70     maxp = max(maxp,cnt[u]);
71 }
72 
73 void readdata()
74 {
75     n = read; k = read;
76     up(i,1,n-1)
77     {
78         int u = read, v = read;
79         add(u,v);
80         add(v,u);
81     }
82     dfs(1);
83     up(i,1,k)
84     {
85         int u = read, v = read;
86         cnt[u]++; cnt[v]++;
87         int LCA = lca(u,v);
88         cnt[LCA]--; cnt[fa[LCA]]--;
89     }
90     dfs_tree(1);
91     printf("%d\n",maxp);
92 }
93 
94 int main()
95 {
96     freopen("input.txt","r",stdin); 
97     readdata();
98     return 0;
99 }

 

转载于:https://www.cnblogs.com/mzg1805/p/10415653.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值