首页 > 其他分享 >P10530 [XJTUPC2024] 生命游戏 题解

P10530 [XJTUPC2024] 生命游戏 题解

时间:2024-05-30 21:34:20浏览次数:32  
标签:int 题解 存活 P10530 maxn XJTUPC2024 include 消除 define

题目大意

一棵树一共 $ n $ 个点如果有 $ k $ 个点与某一个点相连那么这一轮的结尾这个点就会

思路

这道题有几个坑!

  1. 并没有说哪一个节点是根节点。

  2. 双向边记得开双倍数组。

  3. 等这一轮的点消除完了才能再次判断哪一些点可以消除。

首先我们创建一个数组 $ Size_{n} $ 来表示这个点与几个存活的点有连边,既然都说到存活了那么我们还需要创建一个数组 $ life_{n} $ 来表示这个点是否存活。我们还需要注意到一个东西就是消除完点后寻找一个点是否边数为 $ k $,必须是跟这些消除的点所相连的点不然一个点的边数为什么会平白无故的减少。还有最后一个要点再添加消除的点的时候我们要看当前点是否已经被消除过一次了(肯能会有两个消除的点连着同一个点在添加时我们也不好判断)。

最后答案跑一边 dfs 就行了。

如果你全部都懂了的话建议去写吧,代码量极其短我觉得因该是普及组第三题的难度

Code:

#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <queue>
#define sc(ppt) scanf("%d" , &ppt)
#define ll long long
#define prt printf
using namespace std; // 屎山头文件

const int maxn = 1e6 + 1;
bool life[maxn] , vis[maxn]; //life 表示这个点是否存活 vis dfs是表示这个点是否搜索过 
int n , k , Size[maxn] , ans = 0; //size 当前点与几个存活的点相连 
int h[maxn] , cnt = 0;
queue<int> q , p; //q需要消除的点 p被消除完的点判断下一部分该消除哪一些点 
struct edge{
	int next , to;
}e[maxn << 1]; //双边 

inline void add(int u , int v){
	++ cnt;
	e[cnt].next = h[u] ; e[cnt].to = v;
	h[u] = cnt;
} // 链式前向心 

void dfs_ans(int u , int fa){
	vis[u] = 1;
	for(int i=h[u] ; i ; i=e[i].next){
		int v = e[i].to;
		if(v == fa || vis[v] == 1 || life[v] == false) continue;
		dfs_ans(v , u);
	}
} // 树上搜索板子多了几个判断 

signed main(){
	sc(n) ; sc(k) ;
	for(int i=1 ; i<n ; i++){
		life[i] = life[i + 1] = true;
		int u , v ; sc(u) ; sc(v) ;
		add(u , v);
		add(v , u);
		Size[u] ++ ; Size[v] ++;
	} // 输入 
	for(int i=1 ; i<=n ; i++) if(Size[i] == k) q.push(i);
	while(! q.empty()){ // 判断是否还有可以消除的点 
		while(! q.empty()){ // 消除当前需要消除的点 
			int u = q.front() ; q.pop() ; p.push(u);
			if(life[u] == false) continue;
			for(int i=h[u] ; i ; i=e[i].next){
				int v = e[i].to;
				Size[v] --; // 与他有边的点Size-- 
			}
			life[u] = false; // 趋势了 
		}
		while(! p.empty()){ // 寻找下一些需要消除的点 
			int u = p.front() ; p.pop() ;
			for(int i=h[u] ; i ; i=e[i].next){
				int v = e[i].to;
				if(life[v] == true && Size[v] == k) q.push(v);
			}
		}
	}
	for(int i=1 ; i<=n ; i++){
		if(vis[i] == 0 && life[i] == true){ // 看有几个连通块 
			dfs_ans(i , -1);
			++ ans;
		}
	}
	prt("%d" , ans);
	return 0;
}
//CaoSheng' code

标签:int,题解,存活,P10530,maxn,XJTUPC2024,include,消除,define
From: https://www.cnblogs.com/CaoSheng-blog/p/18223270

相关文章

  • CF/505/D 题解
    思路这道题的思路其实是根据样例图片来的。首先第一张:这张图片可以得知$n$个点没有环的时候最少需要$n-1$个点。再看第二张:这个图确实很难思考,但稍微思考一下如果我们把含有一个强连通分量的图变成一整个强连通图。这个图的边数不就变成$n$了吗?来推一下......
  • P6342 [CCO2017] Vera 与道路建设 题解
    题目大意对于一个图w一共有v个点点的编号为1,2,...,v,对于点a与点b如果满足$a\tob$且$b\toa$使得每一条道路都只走过一次,那么我们称$a,b$为完美点对,当一个联通图只有$k$个完美点对时,称这个联通图为美丽公路网,要求求出一个美丽公路网......
  • Nikita and LCM题解
    题目大意给你一个数组$a$,令$t$为$a$的子序列且$t$中所有数的最小公倍数$\notina$求$t$数组中最多有多少个数。思路非常明显这是一道数学题,对于数组$a$我们首先从小到大拍一个序,然后我们可以求出$a$中所有数的最大公倍数,如果这个公倍数$\not=......
  • MITIT 2024 Spring Invitational Qualification 简要题解
    这个比赛没有找到题解,有点难绷,所以来写篇。(实际上是无聊时写的就是了)题面:https://codeforces.com/gym/105125/。目测难度是绿绿黄紫紫。A有点诈骗。其实策略是只保留\(\le3\)个数,然后就随便维护一下。\(O(n\logn)\)。Code#include<bits/stdc++.h>usingnamespaces......
  • Gym-100520A Andrew Stankevich Contest 45 A 题解
    AnalogousSetsGym-100520ASol1.集合生成函数将可重集合\(M\)映射为生成函数:\[F(M)=\sum_{m\inM}(\#m)\cdotx^m\]如果\(M\)的元素在\(\mathbbN\)上取值,那么,\(F(M)\)是多项式。2.\(\theta\)算子\[\theta(F)=x\cdotF'\]其中\(F'=\frac{dF}{dx}\)......
  • Springboot报class path resource [xxxxx.json] cannot be resolved to URL because i
    当Springboot解析resources文件下的json文件时,在本地环境好用,部署到服务器上找不到文件内容报错classpathresource[xxxxx.json]cannotberesolvedtoURLbecauseitdosenotexist问题排查(1)pom.xml文件配置<build><resources><resource><d......
  • 洛谷 P8725 [蓝桥杯 2020 省 AB3] 画中漂流 的题解
    题目大意传送门思路考虑使用时空复杂度为O(tm)O(tm)......
  • 洛谷 P8614 [蓝桥杯 2014 省 A] 波动数列 的题解
    题目大意求满足和为sss且ti=......
  • 列队春游|概率期望|题解
    题面解析前言,此处所述为\(O(n^2)\)算法,暂时未推出\(O(n)\)的算法,后续可能会更新。题意非常明白,不多赘述。我们去考虑单个位置的概率,维护每个人放在该位置对该位置期望的贡献。以这个思想作为切入点,我们思考,对于一个序列来说,如果它的长度是定的。设总人数为n,当前我们考虑......
  • 【23NOIP提高组】题解
    T1:词典 #include<bits/stdc++.h>usingnamespacestd;inlineintread(){ intx=0,f=1;charch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9�......