Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) F

原创 2017年01月03日 15:12:03

题意:

在一片名为treeland的土地上,要举办一次球赛,,这片土地上的n个城市刚好构成一棵树,一共有2k个不同的城市都派出了参赛队伍。首先,要把它们分成k个小组,每个小组刚好两队,每个队只能被分到一组。然后,同一组的两个队会分别在一方的城市进行一场比赛,为此,需要给每组球员安排休息地,每组的休息地要求在该组两个城市最短路径上的一个点。不同组别的休息地可以重叠,要求总的选择的休息地最少。输出最少的休息地数量,以及一个分组方案。 n <= 2E5


solution:

先将这2k个点标记,称作关键点。显然,这棵树上存在一个点,使得以它为根时,所有儿子的子树中,含有关键点数量最大的那个子树的数量不超过k。证明的话,可以先任意找一个点作为目标点,对于它的所有儿子,找到那个含关键点数最多的,如果它的权值小于k,说明找到这个点,否则,目标点往这个儿子调整,其它子树的权值和不超过k,重复执行这种操作,权值最大的那个子树,权值不断减少,总能调整到。

现在找到了这个节点,能证明,在这个点建立休息处,总能找到至少一种配对方案,使得所有路径都经过这个点,只要有办法构造出来就行了。构造的话,每次拿一棵子树,把里面的关键点全部写出来,当所有儿子都操作完以后,就构成一个序列,只要将所有(i,i+k)配对就行了,因为每棵子树的权值不超过k,所以i和i+k一定在两棵不同的子树,既然在不同的子树,就必定经过根

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 2E5 + 20;

int n,k,rt,tot,siz[maxn],A[maxn];
bool bo[maxn];

vector <int> v[maxn];

void Dfs1(int x,int fa)
{
	siz[x] = bo[x] ? 1 : 0;
	for (int i = 0; i < v[x].size(); i++)
	{
		int to = v[x][i];
		if (to == fa) continue;
		Dfs1(to,x); siz[x] += siz[to];
	}
} 

void Dfs2(int x,int fa)
{
	bool pass = 0; int Nex;
	for (int i = 0; i < v[x].size(); i++)
	{
		int to = v[x][i];
		if (to == fa) continue;
		if (siz[to] > k) pass = 1,Nex = to;
	}
	if (!pass) rt = x; else Dfs2(Nex,x);
}

void Dfs3(int x,int fa)
{
	if (bo[x]) A[++tot] = x;
	for (int i = 0; i < v[x].size(); i++)
	{
		int to = v[x][i];
		if (to == fa) continue;
		Dfs3(to,x);
	}
}

int main()
{
	#ifdef DMC
		freopen("DMC.txt","r",stdin);
	#endif
	
	cin >> n >> k;
	for (int i = 1; i < n; i++)
	{
		int x,y; scanf("%d%d",&x,&y);
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for (int i = 1; i <= 2*k; i++)
	{
		int x; scanf("%d",&x); bo[x] = 1;
	}
	Dfs1(1,0); Dfs2(1,0);
	if (bo[rt]) A[++tot] = rt;
	for (int i = 0; i < v[rt].size(); i++)
		Dfs3(v[rt][i],rt);
	printf("1\n%d\n",rt);
	for (int i = 1; i <= k; i++) 
		printf("%d %d %d\n",A[i],A[i+k],rt);
	return 0;
}

版权声明:这个人很懒什么都没有留下

相关文章推荐

Codeforces Round #389 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 3) 总结

这场真是GG,比赛的时候就写出了三道题,还都比较水(可怜的standing才2000 QωQ)。A. Santa Claus and a Place in a Class 题意:有一个n*m的区域,...

Codeforces Round #380 (Div. 1, Rated, Based on Technocup 2017 - Elimination Round 2)

比赛的时候过了3题的pretest,结果systest怒跪2题。。rank几乎垫底。但是这场题目确实比较简单。A. Road to Cinema  cf特别爱出的二分题。。二分汽油容量,得到一个最小的...

Codeforces Round #380 (Div. 2,Based on Technocup 2017 - Elimination Round 2)C - Road to Cine//

C. Road to Cinema time limit per test 1 second memory limit per test 256 megabytes ...

Technocup 2017 - Elimination Round 1 (Unofficially Open for Everyone, Rated for Div. 2) 解题报告

A. Transformation: from A to B题意:一个数a,两种操作,一是把a*2,二是把a*10+1,问把a变到b是否有解和最小次数。思路:两种操作都是指数级别的,爆搜即可。// /...

Technocup 2017 - Elimination Round 1 (Rated for Div. 2) D. T-shirts Distribution 贪心、flows

题意:给出 S,M, L, XL, XXL, XXXL 每种衣服的个数,然后给出每个人的选择,可能只有一种,可能2种中的任一种即可(且只能是大小相邻的两种,且这2种输入的时候是升序排列),求给出的那些...

Technocup 2017 - Elimination Round 1 (Rated for Div. 2) C. Guess the Array 交互题+解n元方程组

题意:交互题+解n元方程组 交互题+解n元方程组 首先询问 ? 1 2 ? 2 3 ? 1 3 然后 x1 + x2 == x12 1) x2 + x3 == x23 ...

Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals)【A,B,C】

翻车!翻车! codeforces782A A题: 水。 代码: #include using namespace std; typedef long long LL; int num...

Technocup 2017 - Elimination Round 1 (Rated for Div. 2) B. Bill Total Value 表达式处理、sstream

题意:每一个物品有自己的价格,求价格总数,并按照要求的格式输出,小数只有2为,且整数部分每3位用一个小数点来分隔。 表达式处理、sstream 全部转化为乘100以后转化为整数加法,(这个过程可能有精...

Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals)A,B,C

A. Andryusha and Socks time limit per test2 seconds memory limit per test256 megabytes inputstand...

Codeforces Round #403 (Div. 2, based on Technocup 2017 Finals) B. The Meeting Place Cannot Be Change

B. The Meeting Place Cannot Be Changed time limit per test 5 seconds memory limit per test 2...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)