题目描述
距离产生美。
一棵包含$n$个点的树,有$2k$个不同的关键点,我们现在需要将这些点两两配对,对于一种形如:
$$(u_1,v_1),(u_2,v_2),...,(u_k,v_k)$$
的配对方案,我们定义其美丽值为:
$$beauty=\sum \limits_{i=1}^k dist(u_i,v_i)$$
(其中$dist(u,v)$表示点$u$到$v$的简单路径的边数)。
现在,请你找出美丽值最大的配对方案的美丽值。
输入格式
第一行包含三个整数$n,k,a$其中$a$为$1$表示有特殊性质,$a$为$0$表示没有特殊性质。
第二行包含$2k$个不同整数$u_1,u_2,...,u_{2k}$,表示关键点。
接下来$-1$行每行包含两个整数$u,v$,表示一条边。
输出格式
输出一行,包含一个整数表示最大的$beauty$值。
样例
样例输入:
7 2 0
1 5 6 2
1 3
3 2
4 5
3 7
4 3
4 6
样例输出:
6
数据范围与提示
样例解释:
样例解释:$(1,6),(2,5)$这种配对方案美丽值最大,为$6(dist(1,6)+dist(2,5)=3+3=6)$。
数据范围:
特殊性质:每个点的度数小于等于$2$
对于所有数据:$1\leqslant u_i,v_i\leqslant n$且$1\leqslant u,v\leqslant n$。
题解
我们用$dp[u]$表示走到$u$这个节点的边最多是多少条,从$u$走到它父亲的边是$min(dp[u],2k-size[u])$,其中$size[u]$表示$u$这棵子树中的关键点数量,$min$的前面一项是$u$最多能提供的条数,后面一项是外面最多能接收的条数,两者较小值即为从$u$到其父亲最多的条数,我们只需要最后统计一下经过每条边的条数的和即可。
时间复杂度:$\Theta(n)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h> using namespace std; struct rec{int nxt,to;}e[200000]; int head[100001],cnt; int n,k,a; int size[100001]; bool u[100001],vis[100001]; long long ans; void add(int x,int y) { e[++cnt].nxt=head[x]; e[cnt].to=y; head[x]=cnt; } void dfs(int x) { if(u[x])size[x]=1; vis[x]=1; for(int i=head[x];i;i=e[i].nxt) if(!vis[e[i].to]) { dfs(e[i].to); size[x]+=size[e[i].to]; } ans+=min(size[x],(k<<1)-size[x]); } int main() { scanf("%d%d%d",&n,&k,&a); for(int i=1;i<=(k<<1);i++){int x;scanf("%d",&x);u[x]=1;} for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);add(x,y);add(y,x);} dfs(1);printf("%d",ans); return 0; }
rp++