本题算法:贪心+排序+搜索+并查集+图论

输入中的t可以不用管,毕竟这只是特殊情况的标志

题目中虽然没有很明确地说明这是一棵树,但是题目中说有n个点,但是只有n-1条边,想用这n-1条边把整个图连通起来,那么只有可能是棵树。(不信可以自己画画看)

竟然是一棵树了,那么就可以用找到每个节点唯一的父亲、爷爷、曾祖父、曾曾祖父、曾曾曾祖父......(此时可以开个数组记录一下每个节点的父亲)。

接下来,运用到了贪心的思想,因为一个小队能控制的最远距离为k,那么找当前最深的没有被访问过的节点的第k位祖宗所能覆盖的节点数才会更多。

找到了当前节点的第k位祖宗,就以这位祖宗为起点,用BFS向四周扩散k个单位,标记被扩散到的节点为已访问。

如果直接这样写,会出现一个问题

第19个点MLE---95分

究竟是哪出问题了呢?问题出在BFS身上,此时需要一个小小的剪枝技巧:

如果当前节点最大扩散出去的单位比现要求扩散的单位还要大的话,此节点就没必要进行扩散了。

具体细节详见代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=100000+1;
int fa[MAXN];//记录父亲节点
int n,k,meiyouyong;
vector<int>ver[MAXN];//存图
struct Node
{
int id;//记录当前节点编号,防止sort时打乱
int deep;//当前节点的深度
}node[MAXN];
int bin[MAXN];//记录每个节点扩散的最大单位,用于剪枝
struct BFS
{
int t;//当前遍历到的节点
int cnt;//扩散cnt个单位
};
bool vis[MAXN];//是否遍历到过
inline int read()
{
int tot=0;
char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
{
tot=tot*10+c-'0';
c=getchar();
}
return tot;
}
inline void init(int now)//初始化
{
for(int i=0;i<ver[now].size();i++)
{
int x=ver[now][i];
if(node[x].deep)continue;
node[x].deep=node[now].deep+1;//深度比父亲深1个单位
node[x].id=x;
fa[x]=now;
init(x);
}
}
inline int find(int now)//找到now节点的第k位祖宗
{
int tot=now;
for(int i=1;i<=k;i++)
{
tot=fa[tot];
}
return tot;
}
inline bool cmp(Node u,Node v)
{
return u.deep>v.deep;
}
inline void bfs(int x)
{
queue<BFS>q;
q.push((BFS){x,k});
vis[x]=1;
while(q.size())
{
BFS now=q.front();
if(now.cnt==0)break;//扩散结束
q.pop();
for(int i=0;i<ver[now.t].size();i++)
{
int x=ver[now.t][i];
if(now.cnt<=bin[x])continue;//剪枝技巧
bin[x]=now.cnt;//更新最大值
vis[x]=1;//标记
q.push((BFS){x,now.cnt-1});
}
}
}
int main()
{
int x,y;
n=read();k=read();meiyouyong=read();
node[1].deep=1;
fa[1]=1;
node[1].id=1;
for(int i=2;i<=n;i++)
{
x=read();y=read();
ver[x].push_back(y);
ver[y].push_back(x);
}
init(1);
sort(node+1,node+1+n,cmp);
/*for(int i=1;i<=n;i++)cout<<fa[i]<<" ";
cout<<endl;*/
int ans=0;
for(int i=1;i<=n;i++)
{
if(vis[node[i].id])continue;
//若此节点已被遍历过,那么就没必要在去找一遍了
int grand=find(node[i].id);
//cout<<grand<<endl;
bfs(grand);
ans++;
//cout<<i<<endl;
}
cout<<ans<<endl;
return 0;
}

洛谷 题解 P3942 【将军令】的更多相关文章

  1. 洛谷 题解 UVA572 【油田 Oil Deposits】

    这是我在洛谷上的第一篇题解!!!!!!!! 这个其实很简单的 我是一只卡在了结束条件这里所以一直听取WA声一片,详细解释代码里见 #include<iostream> #include&l ...

  2. 洛谷 题解 P1600 【天天爱跑步】 (NOIP2016)

    必须得说,这是一道难题(尤其对于我这样普及组205分的蒟蒻) 提交结果(NOIP2016 天天爱跑步): OJ名 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 Libre ...

  3. 洛谷题解P4314CPU监控--线段树

    题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...

  4. 洛谷题解 CF777A 【Shell Game】

    同步题解 题目翻译(可能有童鞋没读懂题面上的翻译) 给你三张牌0,1,2. 最初选一张,然后依次进行n次交换,交换规则为:中间一张和左边的一张,中间一张和右边一张,中间一张和左边一张...... 最后 ...

  5. 洛谷题解 CF807A 【Is it rated?】

    同步题解 题目 好吧,来说说思路: 1.先读入啦~(≧▽≦)/~啦啦啦 2.判断a[i]赛前赛后是否同分数,如果分数不同,则输出,return 0 . 3.如果同分数,则判断a[i]赛前(或赛后)是否 ...

  6. 洛谷题解 P1138 【第k小整数】

    蒟蒻发题解了 说明:此题我用的方法为桶排(我翻了翻有人用了桶排只不过很难看出来,可能有些重复的,这个题只是作为一个专门的桶排来讲解吧) (不会算抄袭吧 ‘QWaWQ’) 简单来说(会的人跳过就行): ...

  7. 【洛谷题解】P2303 [SDOi2012]Longge的问题

    题目传送门:链接. 能自己推出正确的式子的感觉真的很好! 题意简述: 求\(\sum_{i=1}^{n}gcd(i,n)\).\(n\leq 2^{32}\). 题解: 我们开始化简式子: \(\su ...

  8. 洛谷题解 P2865 【[USACO06NOV]路障Roadblocks】

    链接:https://www.luogu.org/problemnew/show/P2865 题目描述 Bessie has moved to a small farm and sometimes e ...

  9. 洛谷题解:P1209 【[USACO1.3]修理牛棚 Barn Repair】

    原题传送门:https://www.luogu.org/problemnew/show/P1209 首先,这是一道贪心题.  我们先来分析它的贪心策略.  例如,样例:  4 50 18  3 4 6 ...

随机推荐

  1. 边学边体验django--模型

    步骤: 1.选定数据库,然后修改 settings.py 中的 DATABASES配置 实验过了sqlite3. 应该是这个样子的: 2. 创建app, 建立数据表模型. python manage. ...

  2. python 使用流式游标 读取mysql怎么不会内存溢出

    使用过java读取mysql大数据量的人应该都知道,如果查询时不开游标不设置一次性区大小的话,会一次性的把所有记录都拉取过来再进行后续操作,数据量一大就很容易出现OOM 如果用python去读取mys ...

  3. learning express step(十一)

    learning express.Router() code: const express = require('express'); const app = express(); var route ...

  4. web软件测试基础系统测试简化理论

    系统测试点主要如下 1.系统测试基础-2.测试对象与测试级别-3.系统测试类型-4.系统测试方法-5.系统测试之软件测试质量. 1.系统测试:是尽可能彻底地检查出程序中的错误,提高软件系统的可靠性. ...

  5. 用MFC构造DIRECTX应用框架

    一. MFC类库与DirectXSDK Microsoft DirectX SDK是开发基于 Windows平台游戏的一个软件开发工具,其主要功能主要包括在五个组件中: DirectDraw. Dir ...

  6. ICEM-圆环孔

    原视频下载地址:https://yunpan.cn/cSKwAIRmFLGe5  访问密码 49c5

  7. 设置Python打印格式

    >>> def esc(code): ... return f'\033[{code}m' ... >>> print(esc('31;1;4') + 'reall ...

  8. django 后台静态文件不显示

    原文链接 https://my.oschina.net/VASKS/blog/874270 django admin svg 不显示.后台显示 xx.svg 200 但浏览器就是不显示. 百度了一圈, ...

  9. Winform 工程反编译后窗体如何显示

    Winform反编译后,如果想要让它象正常的工程一样,可以在窗体编辑器中,编辑,需要做一些工作. 1.  转换.resources 为 .resx 利用resgen工具.这个工具是vs自带的. 在启动 ...

  10. oracle-密码

    Oracle 11g 默认用户名和密码安装ORACLE时,若没有为下列用户重设密码,则其默认密码如下: 用户名/密码 登录身份 说明sys/change_on_install SYSDBA 或 SYS ...