[luogu4268][bzoj5195][USACO18FEB]Directory Traversal
题目大意
给你\(n\)个文件的关系,求出某一个点,这个点到叶节点的长度的总距离最短。(相对长度的定义在题目上有说明)
感想
吐槽一下出题人,为什么出的题目怎么难看懂,我看了整整半个小时,才看懂。
题解
首先数据给我们的是一棵树,一开始我审题不仔细以为是到每个节点的距离最短,就以为是要求树的重心。后来发现不对,而且节点之间的距离不怎么好处理,因为以不同的节点为起点,两节点之间的距离是会变化的。需要用树形dp来解决这个问题,首先预处理出以\(u\)为根节点的子树中有多少个叶节点,因为每一个相对路径的结尾都是没有\(/\)符号的,方便我们计算长度,还要预处理出每一个节点到根节点的长度,因为这个长度是一定的,算出来还是方便计算答案。还有一个是整棵树一共有多少个叶节点,因为在我们计算的节点的上方和下方的计算方法是不一样的。
那么我们树形dp定义状态为\(f[v]\)表示以\(v\)为根节点的最小相对距离之和。
核心的转移方程也是非常好理解的:\(f[v]=f[u]-(len[v]+1)*sz[v]+3*(sum-sz[v])\),解释一下:\(u\)为\(v\)的父亲,为什么是从父亲转移到儿子而不是从儿子转移到父亲?因为越靠近根节点的答案和根节点的答案越接近,每次更改只有一个文件的名字,所以我们先转移到儿子。我们考虑一下,每次我们从父亲节点转移到儿子节点,那么儿子节点以下所有叶子节点都会因为起始节点的改变而减少答案,这个减少的答案是\((len[v]+1)\times sz[v]\),什么意思?因为每次都有一个/号,还有一个\(v\)号字符串的长度,这些答案对于每一个叶子节点都会产生减少。同理在\(v\)节点的另外一侧,也就是\(v\)以上的子树,我们会因为其实节点的降低而增加一段的答案,也就是\(3\times(sum-sz[v])\),\(sum-sz[v]\)表示的是另一半子树中叶节点的个数,\(3\)是因为\(../\)的长度是\(3\),那么转移方程就得到了。
ac代码
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <ctype.h>
# include <iostream>
# include <cmath>
# include <map>
# include <vector>
# include <queue>
# define LL long long
# define ms(a,b) memset(a,b,sizeof(a))
# define ri (register int)
# define inf (0x7f7f7f7f)
# define pb push_back
# define fi first
# define se second
# define pii pair<int,int>
# define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
inline int gi(){
int w=0,x=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
inline LL gll(){
LL w=0,x=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
# define N 200005
struct edge{
int to,nt;
}E[N<<1];
LL H[N],len[N],f[N],sz[N],dis[N];
int cnt,sum,n;
LL ans;
bool isleaf[N];
void addedge(int u,int v){
E[++cnt]=(edge){v,(int)H[u]}; H[u]=cnt;
}
void dfs1(int u){
for (int e=H[u];e;e=E[e].nt){
int v=E[e].to;
dis[v]=dis[u]+len[v]+1; //+1是因为每一次文件之间都有一个/
dfs1(v); sz[u]+=sz[v];
}
if (isleaf[u]) sz[u]=1,dis[u]--,f[1]+=dis[u];//如果是叶节点那么就之间算就可以了
}
void dfs2(int u){
for (int e=H[u];e;e=E[e].nt){
int v=E[e].to;
if (isleaf[v]) continue;
f[v]=f[u]-(len[v]+1)*sz[v]+3*(sum-sz[v]);//转移方程
ans=min(ans,f[v]);
dfs2(v);
}
}
int main(){
// File("DirectoryTraversal");
n=gi();
for (int i=1;i<=n;i++){
char s[20]; scanf("%s",s); len[i]=strlen(s);
int m=gi();
if (m==0) sum++,isleaf[i]=1;
for (int j=1;j<=m;j++){
LL id=gll();
addedge(i,id);
}
}
dfs1(1); ans=f[1]; dfs2(1);
printf("%lld\n",ans);
return 0;
}
[luogu4268][bzoj5195][USACO18FEB]Directory Traversal的更多相关文章
- 【常见Web应用安全问题】---4、Directory traversal
Web应用程序的安全性问题依其存在的形势划分,种类繁多,这里不准备介绍所有的,只介绍常见的一些. 常见Web应用安全问题安全性问题的列表: 1.跨站脚本攻击(CSS or XSS, Cross Si ...
- Web for pentester_writeup之Directory traversal篇
Web for pentester_writeup之Directory traversal篇 Directory traversal(目录遍历) 目录遍历漏洞,这部分有三个例子,直接查看源代码 Exa ...
- luogu4268 Directory Traversal (dfs)
题意:给一个树状的文件结构,让你求从某个文件夹出发访问到所有文件,访问路径字符串长度之和的最小值,其中,访问父节点用..表示,两级之间用/分割 做两次dfs,第一次算DownN[x]和DownS[x] ...
- bzoj 5195: [Usaco2018 Feb]Directory Traversal【树形dp】
注意到目录是一颗树结构,然后就简单了,预以1为根的处理出dis[u]为以这个点为根,到子树内的目录总长,si为子树内叶子数 第二遍dfs换根即可 #include<iostream> #i ...
- Directory traversal
Find the hidden section of the photo galery. 找到相册的隐藏部分. 直接能够目录遍历: 虽然galerie禁止访问,但是密码就在里面----直接爆破或者爬虫 ...
- Spring框架中文件目录遍历漏洞 Directory traversal in Spring framework
官方给出的描述是Spring框架中报告了一个与静态资源处理相关的目录遍历漏洞.某些URL在使用前未正确加密,使得攻击者能够获取文件系统上的任何文件,这些文件也可用于运行SpringWeb应用程序的进程 ...
- USACO比赛题泛刷
随时可能弃坑. 因为不知道最近要刷啥所以就决定刷下usaco. 优先级排在学习新算法和打比赛之后. 仅有一句话题解.难一点的可能有代码. 优先级是Gold>Silver.Platinum刷不动. ...
- 前端学HTTP之web攻击技术
前面的话 简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象.应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标.本文将详细介绍攻击web站点 ...
- web安全性测试用例
建立整体的威胁模型,测试溢出漏洞.信息泄漏.错误处理.SQL 注入.身份验证和授权错误. 1. 输入验证 客户端验证 服务器端验证(禁用脚本调试,禁用Cookies) 1.输入很大的数(如4,29 ...
随机推荐
- Luogu P3327 [SDOI2015]约数个数和
又是恶心的莫比乌斯反演,蒟蒻我又是一脸懵逼的被CXR dalao狂虐. 题目要求\(ans=\sum_{i=1}^n \sum_{j=1}^m d(ij)\),其中\(d(ij)\)表示数\(x\)的 ...
- Luogu P2568 GCD
我们首先发现这样肯定是做不了的,所以我们枚举为\(gcd(x,y)=d\)的\(d\) 然后考虑以下的性质: \(gcd(x,y)=1 \Leftrightarrow gcd(px,py)=p(p为素 ...
- GBDT和随机森林的区别
GBDT和随机森林的相同点: 1.都是由多棵树组成 2.最终的结果都是由多棵树一起决定 GBDT和随机森林的不同点: 1.组成随机森林的树可以是分类树,也可以是回归树:而GBDT只由回归树组成 2.组 ...
- Python爬虫利器二之Beautiful Soup的用法
上一节我们介绍了正则表达式,它的内容其实还是蛮多的,如果一个正则匹配稍有差池,那可能程序就处在永久的循环之中,而且有的小伙伴们也对写正则表达式的写法用得不熟练,没关系,我们还有一个更强大的工具,叫Be ...
- 【强化学习】python 实现 q-learning 迷宫通用模板
本文作者:hhh5460 本文地址:https://www.cnblogs.com/hhh5460/p/10145797.html 0.说明 这里提供了二维迷宫问题的一个比较通用的模板,拿到后需要修改 ...
- DELL升级bios方式
升级过程其实很简单 1.官网下载exe文件,放入U盘 2.重启电脑F12选择升级bios 3.选择U盘里面的升级文件 4.重点来了!!! boot options 是什么? 就是boot设置里面自己自 ...
- SpringBoot日记——Spring的安全配置-登录认证与授权
安全是每个项目开发中都需要考虑的,比如权限控制,安全认证,防止漏洞攻击等. 比较常见的安全框架有:Apache的shiro.Spring Security等等,相信用shiro的用户群体更多,而sec ...
- Linux内核读书笔记第三周 调试
内核调试的难点在于它不能像用户态程序调试那样打断点,随时暂停查看各个变量的状态. 也不能像用户态程序那样崩溃后迅速的重启,恢复初始状态. 用户态程序和内核交互,用户态程序的各种状态,错误等可以由内核来 ...
- Maven遇到github引用的项目有bug怎么办?
Maven遇到github引用的项目有bug,自己想要修复/作者已经修复了但是还没有版本出来. 一个maven的做法 git clone 该项目(可能直接下载zip比较快). 在项目中mvn inst ...
- 第三个Sprint冲刺第八天(燃尽图)