题目大意

给你\(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的更多相关文章

  1. 【常见Web应用安全问题】---4、Directory traversal

    Web应用程序的安全性问题依其存在的形势划分,种类繁多,这里不准备介绍所有的,只介绍常见的一些.  常见Web应用安全问题安全性问题的列表: 1.跨站脚本攻击(CSS or XSS, Cross Si ...

  2. Web for pentester_writeup之Directory traversal篇

    Web for pentester_writeup之Directory traversal篇 Directory traversal(目录遍历) 目录遍历漏洞,这部分有三个例子,直接查看源代码 Exa ...

  3. luogu4268 Directory Traversal (dfs)

    题意:给一个树状的文件结构,让你求从某个文件夹出发访问到所有文件,访问路径字符串长度之和的最小值,其中,访问父节点用..表示,两级之间用/分割 做两次dfs,第一次算DownN[x]和DownS[x] ...

  4. bzoj 5195: [Usaco2018 Feb]Directory Traversal【树形dp】

    注意到目录是一颗树结构,然后就简单了,预以1为根的处理出dis[u]为以这个点为根,到子树内的目录总长,si为子树内叶子数 第二遍dfs换根即可 #include<iostream> #i ...

  5. Directory traversal

    Find the hidden section of the photo galery. 找到相册的隐藏部分. 直接能够目录遍历: 虽然galerie禁止访问,但是密码就在里面----直接爆破或者爬虫 ...

  6. Spring框架中文件目录遍历漏洞 Directory traversal in Spring framework

    官方给出的描述是Spring框架中报告了一个与静态资源处理相关的目录遍历漏洞.某些URL在使用前未正确加密,使得攻击者能够获取文件系统上的任何文件,这些文件也可用于运行SpringWeb应用程序的进程 ...

  7. USACO比赛题泛刷

    随时可能弃坑. 因为不知道最近要刷啥所以就决定刷下usaco. 优先级排在学习新算法和打比赛之后. 仅有一句话题解.难一点的可能有代码. 优先级是Gold>Silver.Platinum刷不动. ...

  8. 前端学HTTP之web攻击技术

    前面的话 简单的HTTP协议本身并不存在安全性问题,因此协议本身几乎不会成为攻击的对象.应用HTTP协议的服务器和客户端,以及运行在服务器上的Web应用等资源才是攻击目标.本文将详细介绍攻击web站点 ...

  9. web安全性测试用例

    建立整体的威胁模型,测试溢出漏洞.信息泄漏.错误处理.SQL 注入.身份验证和授权错误. 1.   输入验证 客户端验证 服务器端验证(禁用脚本调试,禁用Cookies) 1.输入很大的数(如4,29 ...

随机推荐

  1. Jquery 图片延迟加载技术

    参考网址:http://code.ciaoca.com/jquery/lazyload/ 延迟加载能大大增加你网站的加载速度! 需要引入以下文件<Jq文件也是少不了的>: <scri ...

  2. Luogu P2421 [NOI2002]荒岛野人

    最近上课时提到的一道扩欧水题.还是很可做的. 我们首先注意到,如果一个数\(s\)是符合要求的,那么那些比它大(or 小)的数不一定符合要求. 因此说,答案没有单调性,因此不能二分. 然后题目中也提到 ...

  3. [Oracle][DataGuard]Standby数据库文件有损坏时的处理方法

    需要参考: [Oracle]Recovering the primary database's datafile using the physical standby, and vice versa ...

  4. RabbitMQ 延时消息设计

    问题背景 所谓"延时消息"是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 场景一:客户A在十二点下了一个订单,我想半个小时后来 ...

  5. keycloak 调研资料

    1.https://www.keycloak.org/docs/latest/server_development/index.html 下载keycloak 2.https://gitee.com/ ...

  6. 【下一代核心技术DevOps】:(四)私有镜像库阿里云Docker服务使用

    1.使用阿里云镜像库有很多优点 稳定可靠,阿里技术,放心使用. 国内cdn多节点加速,下载速度非常快 可以和阿里云Git代码集成,不需要第三方CI工具,当然带的自动构建服务也可以和其他的Git库集成, ...

  7. SpringBoot日记——ElasticSearch全文检索

    看到标题的那一串英文,对于新手来说一定比较陌生,而说起检索,应该都知道吧. 这个ElasticSearch目前我们的首选,他主要有可以提供快速的存储.搜索.分析海量数据的作用.他是一个分布式搜索服务, ...

  8. Quartz_配置

    quartz_jobs.xml job 任务 其实就是1.x版本中的<job-detail>,这个节点是用来定义每个具体的任务的,多个任务请创建多个job节点即可 name(必填) 任务名 ...

  9. 分布式监控系统Zabbix--完整安装记录-批量添加主机和自动发现端口

    一.Zabbix-3.0.3批量添加主机的配置如下: 0)被监控机上要安装zabbix_agent,并配置好zabbix_agentd.conf (如下172.29.8.50是zabbix_serve ...

  10. 《linux内核设计与实现》第十八章

    第十八章 调试 调试工作艰难是内核级开发区别于用户级开发的一个显著特点. 一.准备开始 1.内和调试需要什么 一个bug(大部分bug通常都不是行为可靠而且定义明确的) 一个藏匿bug的内核版本(知道 ...