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

输入中的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. winfrom 遍历文本框

    //winform中Control是所有组件的基类 ; i <= ; i++) { Control[] coltxtSpeed = this.Controls.Find("txtbox ...

  2. openpyxl -用于读/写Excel 2010 XLSX/XLSM文件的python库

    openpyxl -用于读/写Excel 2010 XLSX/XLSM文件的python库¶ https://www.osgeo.cn/openpyxl/index.html

  3. Ubuntu 在VirtualBox里无法联网【已解决】

    1. 在virtualBox中设置网络:设置->网络->将连接方式选定为“网络地址转换(NAT)” 点确定 2.进入Ubuntu系统中:系统设置->网络, 在弹出的对话框中选择:有线 ...

  4. codeforces#1215E. Marbles(状压dp)

    题目链接: http://codeforces.com/contest/1215/problem/E 题意: 至少多少次操作可以使得相同的数都是相邻的 每次操作可以交换两个相邻的数 数据范围: $1\ ...

  5. VSCode-VUE模板文件

    编辑自己的代码片段 ctrl+shift+p 输入snippet 选择 'Preferences: Configure User Snippets' 输入vue 选择vue.json,会打开vue.j ...

  6. 为ubuntu找个能用的桌面,顺便进行适当的改造

    最近,开始玩ros,结果官方推荐ubuntu linux,虽然都是差不多的linux,无非就是软件包形式不同而已.但是,个人对ubuntu的unity桌面实在是没有爱,最让人无语的是,kubuntu无 ...

  7. Linux 文件存在程序找不到文件

    1. 编码格式 程序运行时的编码格式和传输到程序中参数的编码格式是否一致,可以在程序中打印日志进行验证: 2. 转义符 文件路径中存在转义符 3. 运行程序的用户身份 不同用户运行程序也可能导致编码格 ...

  8. pwn学习日记Day10 《程序员自我修养》读书笔记

    第一章 从 Hello world 说起 抛出问题: 1.程序为什么要被编译器编译后才能执行? 2.编译器在把C语言程序转换成可以执行的机器码的过程中做了什么,怎么做的? 3.最后编译出来的可执行文件 ...

  9. jquery - 定义二维数组

    var products = []; products.push({product_id: '1',count: 3},{product_id:'2',count: 6})

  10. RGB-D(深度图像) & 图像深度

    RGB-D(深度图像)   深度图像 = 普通的RGB三通道彩色图像 + Depth Map   在3D计算机图形中,Depth Map(深度图)是包含与视点的场景对象的表面的距离有关的信息的图像或图 ...