首页 > 其他分享 >CSP2023-12树上搜索题解

CSP2023-12树上搜索题解

时间:2023-12-19 19:06:15浏览次数:26  
标签:index 12 int 题解 CSP2023 sons include LL points

刚考完csp,这道题是大模拟题,题意不难理解。以下是题目链接:

http://118.190.20.162/view.page?gpid=T178

当时考场上这道题调了好久没调出来,忽略了很多细节。在这里分享一下满分题解及思路,帮大家避避坑。

#include <iostream>
#include<stdio.h>
#include<queue>
#include<cstring>
#include<string>
#include <map>
#include<cmath>
#include<cstring>
#include<algorithm>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#define MAX 0x3f3f3f3f3f3f  //注意这个数要开大一点,不然会溢出
using namespace std;
typedef long long LL;

LL n, m;
// 定义结构体记录每个点的信息,包括其父节点,后代集合,以及其权重
struct point {
	int father;
	unordered_set<int> sons;
	LL weight;
} points[2010];
// 记录每个结点是否被去除
bool used[2010];
// 计算当前剩下的结点的总权重
LL calv(){
	LL sum = 0;
	for (int i = 1;i <= n;i++) {
		if (!used[i]) sum += points[i].weight;
	}
	return sum;
}
// 用于判断需要测试的点是否是提问点的后代
bool searchfa(int x,int fa) {
	if (x == 0) return false;
	if (fa == points[x].father || fa == x)	return true;
	else return searchfa(points[x].father,fa);
}
// 用于构建树
bool fillfa(unordered_set<int> x, int fa) {
	if (fa == 0) return false;
	unordered_set<int>::iterator it;
	for (it = x.begin();it != x.end();it++) {
		points[fa].sons.insert(*it);
	}	
	fillfa(x,points[fa].father);
}
// 用于初始化used数组
void fill(int x) {
	if(x==0)for (int i = 1;i <= n;i++) used[i]=false;
	else for (int i = 1;i <= n;i++) used[i] = true;
}
int main() {
	// 输入部分
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> points[i].weight;
	}
	points[1].father = 0;
	for (int i = 2;i <= n;i++) {
		int a;
		cin >> a;
		points[i].father = a;
		points[i].sons.insert(i);
		fillfa(points[i].sons,a);
		points[i].sons.erase(i);
	}
	// 先求出提问结点,根据测试点是否是其后代分为两类处理
	for (int i = 1;i <= m;i++) {
		LL target;
		LL remain = n;
		fill(0);
		cin >> target;
		// remain记录当前剩余节点数量,为1退出
		while (remain != 1) {
			LL sum = calv();
			int index = 0;
			LL w = MAX;
			// 求出提问结点index
			for (int i = 1;i <= n;i++) {
				if(!used[i]) {
					unordered_set<int>::iterator it;
					LL sum1 = points[i].weight;
					for (it = points[i].sons.begin();it != points[i].sons.end();it++) {
						if(!used[*it])
							sum1 += points[*it].weight;;
					}
					if (abs(sum - 2 * sum1) < w) {
						w = abs(sum - 2 * sum1);
						index = i;
					}
				}
			}
			cout << index << " ";
			// 根据测试点是否是其后代分为两类处理,是后代保留测试点子树
			if(searchfa(target,index)){
				for (int i = 1;i <= n;i++) {
					if(!points[index].sons.count(i))
						used[i] = true;
				}
				used[index] = false;
				remain = 1;
				unordered_set<int>::iterator it;
				for (it = points[index].sons.begin();it != points[index].sons.end();it++) {
					if(!used[*it])
						remain += 1;
				}
			}
			// 不是后代则去除测试点子树
			else{
				used[index] = true;
				remain -= 1;
				unordered_set<int>::iterator it;
				for (it = points[index].sons.begin();it != points[index].sons.end();it++) {
					
					if(!used[*it])remain -= 1;
					used[*it] = true;
				}
			}
		}
		cout << endl;

	}
	return 0;
}

标签:index,12,int,题解,CSP2023,sons,include,LL,points
From: https://blog.51cto.com/u_16291027/8891897

相关文章

  • syoj.1827. 线段传送带题解
    前情提要-三分1827.线段传送带P2571[SCOI2010]传送带省流:三分套三分。在二维平面上有两个传送带,一个从A点到B点,一个从C点到D点,速度分别是p和q,在平面内其他点的速度为r。求A点到D点的最小速度。考虑从A到D的路程一定是\(AE+EF+FD\),即通过这两个点连......
  • 【笔记】2023.12.19:题目选讲
    笔记2023.12.19:题目选讲不会的题目没在这里展现。一共14道题。gym103371IOrganizingColoredSheets猜结论:两个同一行的sharp的间隙的\(\min\)是\(W\)上界,同一列的sharp的间隙的\(\min\)是\(H\)上界,然后相乘。这是假的,是答案上界,过不去样例二。每个\(H\)对......
  • Debian12通过TigerVNC Server远程虚拟桌面并设置开机启动
    1.背景在某些情况,我们想要对某些没有显示器的Linux服务器进行桌面远程操控,于是TigerVNCServer就是我们的首选。2.安装环境首先安装桌面环境gnome与gdm3sudoaptinstallgnomegdm3然后安装TigerVNCServersudoaptinstalltigervnc-standalone-server3.配置安装之后......
  • 你牛什么牛 (女汉子版) - 唐古 发行时间:2014年12月25日
    唐古演唱的歌曲《你牛什么牛》是甜心才女唐古为微电影《我们都是女汉子》演唱的主题曲。发行时间:2014年12月25日  你牛什么牛(女汉子版)-唐古词:师立宅曲:李风持编曲:南少东后期:王路遥总监制:刘晓洪出品人:石太锋你牛你牛你牛你呀牛什么牛你牛你牛你牛你呀牛什......
  • 20231219
    j使用final框架时localhost打不开的界面 由于网络协议的问题原文参考win10localhost解析为::1的解决办法-CSDN博客......
  • 文心一言 VS 讯飞星火 VS chatgpt (160)-- 算法导论12.4 2题
    二、用go语言,请描述这样一棵有n个结点的二叉搜索树,其树中结点的平均深度为O(lgn),但这棵树的高度是w(lgn)。一棵有n个结点的二叉搜索树中结点的平均深度为O(lgn),给出这棵树高度的一个渐近上界。文心一言:二叉搜索树(BinarySearchTree,BST)是一种特殊的二叉树,它对于每个节点都......
  • 【2023潇湘夜雨】WIN11_Pro_Canary_26016.1000软件选装纯净版12.19
    【系统简介】=============================================================1.本次更新母盘来自WIN11_Pro_Canary_26016.1000。2.增加部分优化方案,手工精简部分较多,干掉右下角水印。3.OS版本号为26016.1000。精简系统只是为部分用户安装,个别要求高的去MSDN下。4.集成《DrvCeo-2.1......
  • MySQL 8.0 OCP 125
    Choosethebestanswer.Youencounteredaninsufficientprivilegeerrorinthemiddleofalongtransaction.您在长事务中遇到了不足的权限错误。Thedatabaseadministratorisinformedandimmediatelygrantstherequiredprivilege:通知数据库管理员并立即授予所需......
  • 12.9
    马上就要考四六级了赶紧又背了背单词和作文 Whethertechnologywillmakepeoplelazy“科技是否使人变懒”。Directions: Forthispartyouareallowed30minuitestowriteanessayonwhethertechnologywillmakepeoplelayYoushouldwriteatleast120words......
  • CF1733D1 题解
    原题传送门题目大意给定两个长度为\(n\)的二进制字符串\(a\)和\(b\),你可以进行若干次操作,对于每次操作:选两个数\(l\)和\(r\),且\(l<r\),将\(a_l\)和\(a_r\)交换。如果选取的\(l\)和\(r\)相邻,代价为\(x\),否则为\(y\)。保证\(y≤x\),求出最小代价使得\(a=......