我是靠谱客的博主 花痴豌豆,最近开发中收集的这篇文章主要介绍codeforces 702B,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题意:给出n个城镇,k对学校,k对学校分布在不同的城镇,然后给出2*k个学校所在城镇的编号,然后再给出n-1条边连接的两个城镇,保证每一个城镇都能到达任何一个其他城镇,2*k个学校可以任意配对,要求每一队配对的学校的距离总和最大,每一条边的距离是1

思路:如果对于一个点而言,如果这些学校分布在这个点的左子树和右子树,那么我们可以求出这些学校到这个点的距离然后加起来就是结果,但是题目并不保证这个条件,这时我们可以算每一条边对答案的贡献,对一条边而言,左边如果有a个学校,右边肯定是2*k-a个学校,那么肯定少的那一边要连到多的那一边去,那么答案就是min(a, 2*k-a),这个就直接在树上求结果就行了, 这题答案要用long long 来存,

#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int qq = 200000+10;
vector<int>v[qq];
ll dp[qq]={0};
int vis[qq]={0};
ll ans = 0;
ll n,k;
void dfs(int rt, int fa){
	if(vis[rt]) dp[rt] = 1;
	for(int i=0; i<v[rt].size(); ++i){
		int to = v[rt][i];
		if(to==fa)	continue;
		dfs(to, rt);
		dp[rt]+=dp[to];
		ans+=min(dp[to], 2*k-dp[to]);
	}
}
int main(){
	scanf("%lld%lld",&n, &k);
	int x;
	for(int i=1; i<=2*k; ++i){
		scanf("%d",&x);
		vis[x]++;
	}
	for(int i=1; i<n; ++i){
		int a,b;
		scanf("%d%d",&a, &b);
		v[a].push_back(b);
		v[b].push_back(a);
	}
	dfs(1, -1);
	printf("%lldn", ans);
	return 0;
}


最后

以上就是花痴豌豆为你收集整理的codeforces 702B的全部内容,希望文章能够帮你解决codeforces 702B所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部