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

输入中的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. 12、生命周期-@Bean指定初始化和销毁方法

    12.生命周期-@Bean指定初始化和销毁方法 Bean的生命周期:创建->初始化->销毁 容器管理bean的生命周期 我们可以自定义初始方法和销毁方法,容器在bean进行到当期那生命周期 ...

  2. P4475 巧克力王国 k-d tree

    思路:\(k-d\ tree\) 提交:2次 错因:\(query\)时有一个\(mx\)误写成\(mn\)窝太菜了. 题解: 先把\(k-d\ tree\)建出来,然后查询时判一下整个矩形是否整体\ ...

  3. JAVA中的getBytes()方法

    在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这个表示在不同情况下,返回的东西不一样! String.getBytes(String decode)方 ...

  4. classpath详解

    在dos下编译java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候.classpath就是存放.class等编译后文件的路径. javac:如果当前你要编译的java文件中 ...

  5. Python经典练习题1:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?

    Python经典练习题 网上能够搜得到的答案为: for i in range(1,85): if 168 % i == 0: j = 168 / i; if i > j and (i + j) ...

  6. root of context hierarchy

    Spring Boot项目,运行不明中断.日志如下: 2018-11-03 11:03:43.358 INFO [Thread-2][AbstractApplicationContext.java:9 ...

  7. JMeter压力测试及并发量计算-1

    一.JMeter的安装(Linux) 1. 下载JMeter:这个就不细说了,直接去(http://jmeter.apache.org/download_jmeter.cgi)下载. 2. 解压:ta ...

  8. FIREDAC返回多结果集

    FIREDAC返回多结果集 以前使用ADO, 如果SQL返回的结果集有多个 可以通过NextRecordset来依次获取 代码移植到FireDAC, 对于多结果集处理差不多, 但是还是有一些不一样的地 ...

  9. Maven-Profile 环境隔离

    作用 快速切换不同的配置环境,比如开发时是连接的本地数据库,发布线上时是另外的数据库,每次编译打包时都要修该配置文件比较麻烦,这时就可以使用环境隔离了. 配置 本地(Local), 开发(Dev), ...

  10. JMeter-jp@gc - PerfMon Metrics Collector-CPU监控工具的配置及使用(win版本)

    服务器端放这个 如果端口号被占用,默认报这个错: 如果默认的4444端口被占用的修改: C:\Users\Administrator>CD E:\E:\apache-jmeter-4.0\Ser ...