题目描述
奶牛 Bessie 出人意料地精通计算机。她在谷仓的电脑上将所有珍贵文件存储在一系列目录中;例如:
bessie/
folder1/
file1
folder2/
file2
folder3/
file3
file4
有一个单一的"顶级"目录,名为 bessie
。
Bessie 可以导航到她想要的任何目录。从给定目录中,任何文件都可以通过"相对路径"引用。在相对路径中,符号 ..
表示父目录。如果 Bessie 在 folder2
中,她可以通过以下方式引用四个文件:
../file1
file2
../../folder3/file3
../../file4
Bessie 希望选择一个目录,使得从该目录到所有文件的相对路径长度之和最小。
输入格式
第一行包含一个整数 N(2≤N≤100,000),表示文件和目录的总数。为了输入方便,每个对象(文件或目录)被分配一个唯一的整数 ID,范围在 1 到 N 之间,其中 ID 1 表示顶级目录。
接下来是 N 行。每行以文件或目录的名称开头。名称仅包含小写字母 a-z
和数字 0-9
,且长度最多为 16 个字符。名称后是一个整数 m。如果 m 为 0,则该实体是一个文件。如果 m>0,则该实体是一个目录,并且它内部共有 m 个文件或目录。在 m 之后是 m 个整数,表示该目录中实体的 ID。
输出格式
输出所有文件的相对路径长度的最小可能总和。请注意,此值可能超过 32 位整数的范围。
显示翻译
题意翻译
输入输出样例
输入 #1
8
bessie 3 2 6 8
folder1 2 3 4
file1 0
folder2 1 5
file2 0
folder3 1 7
file3 0
file4 0
输出 #1
42
说明/提示
此输入描述了上面给出的示例目录结构。
最佳解决方案是位于 folder1
中。从该目录中,相对路径为:
file1
folder2/file2
../folder3/file3
../file4
题目来源:Mark Gordon
参考代码:
cpp
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int tot,m,s[N],n,h[N*2],to[N*2],ne[N*2],dp[N],num[N],js,ans;
void add(int a,int b)
{
tot++;
ne[tot]=h[a];
h[a]=tot;
to[tot]=b;
}
void dfs1(int y,int fa)
{
int j1=0;
for(int i=h[y];i;i=ne[i])
{
int j=to[i];
if(j==fa)continue;
j1++;
dfs1(j,y);
num[y]+=num[j];
dp[y]+=dp[j]+s[j]*num[j]+num[j];
}
if(!j1)
{
js++;
num[y]=1;
}
}
void dfs2(int y,int fa)
{
for(int i=h[y];i;i=ne[i])
{
int j=to[i];
if(j==fa)continue;
dp[j]=(js-num[j])*3+dp[y]-(num[j])*s[j]-num[j];
ans=min(ans,dp[j]-js);
dfs2(j,y);
}
}
signed main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;
int a,b;
string str;
for(int i=1;i<=n;i++)
{
cin>>str;
s[i]=str.size();
cin>>m;
for(int j=1;j<=m;j++)
{
cin>>a;
add(a,i);
add(i,a);
}
}
dfs1(1,0);
ans=dp[1]-js;
dfs2(1,0);
cout<<ans;
return 0;
}