[USACO18JAN]Cow at Large P
Description:
贝茜被农民们逼进了一个偏僻的农场。农场可视为一棵有 \(N\) 个结点的树,结点分别编号为 \(1,2,\ldots, N\) 。每个叶子结点都是出入口。开始时,每个出入口都可以放一个农民(也可以不放)。每个时刻,贝茜和农民都可以移动到相邻的一个结点。如果某一时刻农民与贝茜相遇了(在边上或点上均算),则贝茜将被抓住。抓捕过程中,农民们与贝茜均知道对方在哪个结点。
Hint:
\(n \le 7*10^4\)
Solution:
很有趣的题
题解大多是点分治做法
但是由于我的点分治太菜
便学习了这种神仙做法,还跑到了\(luogu\) \(rk5\)?
设牛在rt处出发,现在处于u,并且有叶子v
不难发现我们需要预处理出每个点到它最近叶子节点的距离
然后根据 $dep[rt]-dep[u] \le dep[u]-dep[v] $
来判断这个叶子是否可以放农民来控制它
如果可以,则return,因为越早控制住这个点,答案就越小
首先,显然一条链上的答案都是相等的
所有考虑把链缩成边,再暴力每个点\(dfs\)
这样复杂度就会降下来,不过貌似会被菊花图卡飞?
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=7e4+5;
int n,tot,cnt,ans,x,y,w,f[mxn],in[mxn],hd[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline void chkmax(register int &x,register int y) {if(x<y) x=y;}
inline void chkmin(register int &x,register int y) {if(x>y) x=y;}
queue< int > q;
int ev;
struct ed {
int to,nxt,go,w,fa;
}t[mxn<<1];
inline void add(register int u,register int v) {
t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
}
void bfs()
{
for(register int i=1;i<=n;++i)
if(in[i]==1) q.push(i),f[i]=0;
else f[i]=-1;
while(!q.empty()) {
register int u=q.front(); q.pop();
for(register int i=hd[u];i;i=t[i].nxt) {
register int v=t[i].to;
if(f[v]==-1) {
f[v]=f[u]+1;
q.push(v);
}
}
}
} //使用广搜巧妙地处理f数组
void dfs1(register int u,register int fa,register int d) {
if(fa&&in[u]!=2) {x=u,ev=fa,w=d;return ;} //对于每个点只处理它周围的链,保证复杂度
for(register int i=hd[u];i;i=t[i].nxt) {
register int v=t[i].to;
if(v==fa) continue ;
dfs1(v,u,d+1);
t[i].go=x,t[i].fa=ev,t[i].w=w-d; //缩边,细节稍多
}
}
void dfs2(register int u,register int fa,register int d)
{
if(f[u]<=d) {
++ans;
return ;
}
for(register int i=hd[u];i;i=t[i].nxt) {
if(t[i].to!=fa)
dfs2(t[i].go,t[i].fa,d+t[i].w); //在新图上算答案
}
}
int main()
{
n=read(); register int u,v;
for(register int i=1;i<n;++i) {
u=read(); v=read();
add(u,v); add(v,u);
++in[u]; ++in[v];
}
bfs();
for(register int i=1;i<=n;++i)
if(in[i]!=2) {dfs1(i,0,0);}
for(register int i=1;i<=n;++i) {
if(in[i]==1) {
puts("1");
continue ;
}
ans=0; dfs2(i,0,0);
printf("%d\n",ans);
}
return 0;
}
[USACO18JAN]Cow at Large P的更多相关文章
- [USACO18JAN]Cow at Large G(树形DP)
P4186 [USACO18JAN]Cow at Large G(树形DP) Luogu4186 设dp[i]表示i点需要放多少个农民.则有 \(if(near[i]-dep[i]<=dep[i ...
- luogu P4183 [USACO18JAN]Cow at Large P
传送门 首先考虑N^2做法,每次从一个点出发,如果到达一个点,然后到达这个点的时间\(\le\)离这个点最近的叶子距离\(di_x\),那么答案+1,否则继续找点 这个暴力很不好优化.可以这样认为,如 ...
- P4186 【[USACO18JAN]Cow at Large G】
思路是覆盖子树,我们发现,农民想截住牛的最优策略是不断向上来尽可能地覆盖更大的子树 我们想要尽早地覆盖一个子树,一个显然的贪心是在这个子树中选取深度最小的一个放农民 如果我们在一个点放置了农民,那么其 ...
- [USACO18JAN] Cow at Large G (dfs)
题目大意:有一只狐狸从给定的S点开始逃跑(出发),向叶节点移动以逃离这棵树,叶节点可能出现农民去抓捕狐狸,当农民和狐狸出现在同一个节点的时候,狐狸会被抓住,农民和狐狸移动速度相同,求抓捕狐狸所需要的最 ...
- [洛谷P4183][USACO18JAN]Cow at Large P
题目链接 Bzoj崩了之后在洛谷偶然找到的点分好题! 在暴力的角度来说,如果我们$O(n)$枚举根节点,有没有办法在$O(n)$的时间内找到答案呢? 此时如果用树形$dp$的想法,发现是可做的,因为可 ...
- 洛谷 P4183 - [USACO18JAN]Cow at Large P(点分治)
洛谷题面传送门 点分治 hot tea. 首先考虑什么样的点能够对以 \(u\) 为根的答案产生 \(1\) 的贡献.我们考虑以 \(u\) 为根对整棵树进行一遍 DFS.那么对于一个点 \(v\), ...
- [LOJ#2386]. 「USACO 2018.01 Platinum」Cow at Large[点分治]
题意 题目链接 分析 假设当前的根为 rt ,我们能够在奶牛到达 \(u\) 之时拦住它,当且仅当到叶子节点到 \(u\) 的最短距离 \(mn_u \le dis_u\) .容易发现,合法的区域是许 ...
- BZOJ5189: [Usaco2018 Jan]Cow at Large 贪心+LCA
BZOJ没有题面QAQ,题目链接 洛谷有:题目链接 这题首先要读懂题..(洛谷的翻译有点迷 就是指定根节点,然后可以在叶子结点放个人,然后奶牛在根,问最少要在叶子结点放多少人才能让奶牛走不到叶子结点( ...
- luogu P4183 Cow at Large P (暴力吊打点分治)(内有时间复杂度证明)
题面 贝茜被农民们逼进了一个偏僻的农场.农场可视为一棵有N个结点的树,结点分别编号为 1,2,-,N .每个叶子结点都是出入口.开始时,每个出入口都可以放一个农民(也可以不放).每个时刻,贝茜和农民都 ...
随机推荐
- axios 发送json数据
var qs = require('qs'); axios.post(ajaxurl,qs.stringify({ username:'zhangsan', age:'18' })).then(fun ...
- asp.net core 图片验证码,后台验证
验证方法: public static string VerificationCodeCacheFormat="vcode_cache_{0}"; public IActionRe ...
- Just oj 2018 C语言程序设计竞赛(高级组)H: CBT?
H: CBT? 时间限制: 1 s 内存限制: 128 MB 提交 我的状态 题目描述 对于二叉树,如果这棵树的节点排布是按行从上到下,每行从左到右挨个放置,中间不会有空闲的节点. ...
- 51 nod 1212 无向图最小生成树(Kruckal算法/Prime算法图解)
1212 无向图最小生成树 N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树. 收起 输入 第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量.(2 <= N < ...
- STL用法大全
1. 概述 泛型编程思想最早缘于A.Stepanov提出的部分算法可独立于数据结构的论断.20世纪90年代初A.Stepanov和Meng Lee根据泛型编程的理论用C++共同编写了STL.但直 ...
- python---通过递归和动态规划策略解决找零钱问题
也是常见套路. # coding = utf-8 def rec_mc(coin_value_list, change, know_results): min_coins = change if ch ...
- Java连接MySQL数据库三种方法
好久没有更新博客了!今天利用周目时学习了一下数据库mysql.介绍一下数据库的三种连接方式! 开发工具:Myeclipse MySQL5.6 MySQL连接驱动:mysql-connector-jav ...
- BETA准备
过去存在的问题 文档问题 未能事先做好设计文档,且小程序与后端数据库接口存在问题 界面问题 原型图设计花的时间较少,小程序设计界面仍相对粗糙,前端成员css元素应用经验不足 小程序界面之间对接存在问题 ...
- 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)
本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...
- C#搭建Oauth2.0认证流程以及代码示例
我认为对于一个普遍问题,必有对应的一个简洁优美的解决方案.当然这也许只是我的一厢情愿,因为根据宇宙法则,所有事物总归趋于混沌,而OAuth协议就是混沌中的产物,不管是1...0a还是2.,单看版本号就 ...