专栏文章
题解:P4268 [USACO18FEB] Directory Traversal G
P4268题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minrv9rx
- 此快照首次捕获于
- 2025/12/02 07:20 3 个月前
- 此快照最后确认于
- 2025/12/02 07:20 3 个月前
容易看出,所有的目录形成了一棵有根树。
首先假设从 号点出发,算出此时长度。
定义 为以 为根的子树中文件的数量, 为所有文件的数量。
假设我们已经知道了从节点 出发时的答案 ,那么将出发点变为其子节点 ,节点 下包含的所有文件都长度都会减少 ,而不在 节点下的所有文件访问距离都会增加 (需要多访问一次父目录)。
因此,从 到 , 节点的答案即是:
。
从 号点出发,不断访问子节点,比较每个子节点的大小即可。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node{
string name;
vector<int>son;
int soncnt;
}a[100005];
int siz[100005];
int fcnt;
int cnt=0,ans=LLONG_MAX;
void dfs(int now,int fa,int dis){
if(a[now].soncnt==0){
siz[now]=1;
cnt+=dis-1;
return;
}
for(int i=0;i<a[now].soncnt;i++){
int v=a[now].son[i];
if(v==fa)continue;
dfs(v,now,dis+1+a[v].name.length());
siz[now]+=siz[v];
}
}
void dfs2(int now,int fa,int discnt){
ans=min(ans,discnt);
for(int i=0;i<a[now].soncnt;i++){
int v=a[now].son[i];
if(v==fa)continue;
// if(a[v].soncnt==0)continue;
dfs2(v,now,discnt-(siz[v]*(a[v].name.length()+1-(a[v].soncnt==0)))+(fcnt-siz[v])*3);
}
}
signed main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].name>>a[i].soncnt;
for(int j=1;j<=a[i].soncnt;j++){
int x;
cin>>x;
a[i].son.push_back(x);
}
if(a[i].soncnt==0)fcnt++;
}
dfs(1,0,0);
dfs2(1,0,cnt);
cout<<ans;
return 0;
}
/*
2
folder1 1 2
file1 0
1
file1 0
*/
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...