首页 > 其他分享 >CF1943C - Tree Compass | 树的直径 思维

CF1943C - Tree Compass | 树的直径 思维

时间:2024-03-18 22:48:05浏览次数:43  
标签:int 染色 top Tree Compass 操作 CF1943C include 直径

links

给定一棵 \(n\) 个点的树,可以执行任意次以下操作:选定一个距离 \(u\) ,并将与 \(u\) 距离为 \(d\) 的点都染色。求使得所有节点都染上颜色的最小操作次数,并输出方案。
\(n \leq 2000\)

看着数据范围,朝着 \(O(n^2)\) 的 dp 去想,但是没有想出来。然后又尝试大胆猜测, \(d\) 只有可能等于 \(1\) ,但是这个结论很不靠谱。尝试过从链的角度切入,但感觉没有什么东西可以挖掘,然后就弃了。

然后赛后发现看错题了,以为每个节点只能操作一次。

绷不住了

实际上链的情形很好想。关键是怎么挪到一般的树上。这个桥梁就是树的直径。找到树的直径,然后从直径中点一圈一圈往外染色,这样必然能够染完。

如何证明是最优方案?

因为一次操作最多将直径上的两个点染色,上面给出的方案也一样。所以不管怎么操作,都不会更优。

关键是怎么想到是直径呢……这就很玄学

所以为什么 \(n\) 要给 \(2000\) ……

#include <iostream>
#include <cstdio>
#include <cstring>
	using namespace std;
	const int N = 2005;
struct Edg {
	int lst, ed;
}e[N << 1];
	int n = 0, ne = 0;
	int nte[N], dis[N], fa[N], sta[N];
void NewEdg(int u, int v) {
	ne++;
	e[ne].lst = nte[u];
	e[ne].ed = v;
	nte[u] = ne;
}
void dfs(int x) {
	for (int i = nte[x]; i; i = e[i].lst) {
		if (e[i].ed == fa[x]) continue;
		dis[e[i].ed] = dis[x] + 1;
		fa[e[i].ed] = x;
		dfs(e[i].ed);
	}
}
int GetFar(int x) {
	dis[x] = 1; fa[x] = 0; 
	dfs(x);
	int p = 1;
	for (int i = 2; i <= n; i++)
		if (dis[i] > dis[p]) p = i;
	return p;
}
int main() {
	int T = 0;
	scanf("%d", &T);
	for (int G = 1; G <= T; G++) {
		scanf("%d", &n);
		ne = 0;
		for (int i = 1; i <= n; i++)
			nte[i] = 0;
		for (int i = 1; i <= n - 1; i++) {
			int u = 0, v = 0;
			scanf("%d%d", &u, &v);
			NewEdg(u, v);
			NewEdg(v, u);
		}
		int x = GetFar(1);
		int y = GetFar(x);
		int p = y, top = 0;
			while(p) {
				sta[++top] = p;
				p = fa[p];
			}
		if (dis[y] & 1) {
			printf("%d\n", dis[y] / 2 + 1);
			p = sta[top / 2 + 1];
			for (int i = 0; i <= dis[y] / 2; i++)
				printf("%d %d\n", p, i);
		} else {
			printf("%d\n", dis[y] / 2 + (dis[y] % 4 == 2));
			p = sta[top / 2];
			for (int i = 1; ; i += 2) {
				if (top / 2 - i <= 0 && top / 2 + i > top)
					break;
				printf("%d %d\n", p, i);
			}
			p = sta[top / 2 + 1];
			for (int i = 1; ; i += 2) {
				if (top / 2 - i <= 0 && top / 2 + i > top)
					break;
				printf("%d %d\n", p, i);
			}
		}
	}
	return 0;
} 

标签:int,染色,top,Tree,Compass,操作,CF1943C,include,直径
From: https://www.cnblogs.com/kirakiraa/p/18081582

相关文章

  • git worktree学习
    转自:https://blog.csdn.net/qq_35067322/article/details/1215514691.介绍当在一个仓储下,在A分支编译时,是不能切到B分支上工作的,只能等着A编译完成,很影响效率。所以可以使用worktree命令新建一个工作分支。步骤1:在A分支上编译中,使用以下命令新建一个目录。gitworktreeadd.......
  • 数据结构之BTree、B+Tree的含义及区别
    原文链接:https://blog.csdn.net/weixin_43407520/article/details/1142404381.引言前面学习索引时,了解到MySQL索引的数据类型有B+Tree索引和哈希索引,本文将详细介绍一下BTree和B+Tree的含义和他们的区别。2.BTree2.1概念B树是一种自平衡树数据结构,它维护有序数据并允许以对数时......
  • CodeForces 1943C Tree Compass
    洛谷传送门CF传送门发现对于一条链,一次操作最多能染黑这条链上的\(2\)个点。所以我们把直径拎出来,设直径长度为\(d\)。考虑一条长度为\(d\)的链至少要多少次能全染黑。若\(d\)为奇数,显然从直径中点\(u\)开始做\((u,0),(u,1),\ldots,(u,\frac{d-1}{2})\)......
  • [ABC258F] Main Street 题解
    题意:你要在平面直角坐标系中行走,每一步可以上下左右四个方向任意移动$1$,耗时$k$秒。特别地,存在若干条快速通道,若该步起点和终点均满足$x\equiv0\pmod{B}$或$y\equiv0\pmod{B}$,则认为该步是在快速通道上进行,仅需耗时$1$秒。询问从$(S_x,S_y)$到$(G_x,G_y)$最......
  • P2633 Count on a tree 题解
    题目链接:Countonatree大概可以认为是树上主席树的板子我在之前的某些题解提到了,主席树一般来说有两个基本功能:可持久化功能,可以选择回退或者新增版本。对于可差性问题,可以有更好的转化为前缀和做法,常见的问题为权值类型问题。在树上的路径第\(k\)大,显然如果我们能......
  • [CF1943C] Tree Compass 题解
    不会2300,完蛋了/lh题目链接题目分析容易想到先求出直径,然后以直径中点为圆心画\({d\over2}+O(1)\)个圆。具体地,设直径点数为\(d\)。当\(d\)为奇数时,上述构造需要\(d+1\over2\)次操作;当\(d\)为偶数时,上述构造需要\({d\over2}+1\)次操作。尝试证明上述......
  • QT TreeWidget控件实现文件树 展示目录结构
    目录1、获取盘符,以及一级子文件2、getFileOnDirectory函数,遍历指定文件夹的一级子文件3、绑定展开信号和槽函数,遍历指定文件4、QTreeWidgetItem::setData()用法如图所示,这里仅仅实现展示目录结构,对于新增文件、修改文件、删除文件会后续补充。 思路:这里我并没有在程序......
  • [mysql必备面试题]-mysql索引(B+ Tree )
    一B+Tree原理 1.数据结构BTree指的是BalanceTree,也就是平衡树。平衡树是一颗查找树,并且所有叶子节点位于同一层。B+Tree是基于BTree和叶子节点顺序访问指针进行实现,它具有BTree的平衡性,并且通过顺序访问指针来提高区间查询的性能。在B+Tree中,一个节点......
  • SourceTree提示Authentication failed for 如何解决
    sourcetree拉取失败提示Authenticationfailed(下图)1、关闭sourcetree;2、打开文件目录C:\Users\****\AppData\Local\Atlassian\SourceTree,删除passwd文件;3、打开sourcetree,点击拉取,就会弹出身份验证窗口,输入完成点击login即可拉取成功; ......
  • Dev TreeList 树形结构
    一.您将treeList.OptionsView.ShowCheckBoxes设置为True,树形结构前就会出现CheckBox选择框,如果您想达到选择父节点,子节点也同时选中的效果,需将treeList.OptionsBehavior.AllowRecursiveNodeChecking设置为True。  设置完即可看到效果,如图: 二.获取选中行数据privatevo......