1:我感觉这题的复杂度是假的。
2:我感觉我的编译器是假的。
AC代码如下(而且可以看到跑得飞快)
#include <bits/stdc++.h>
using namespace std;
const int N=100020;
int up[N][30],all[N][30],p[N],n,k;
vector <int> vt[N];
void find_up(int x,int fa){
for(int i=0;i<vt[x].size();i++){
int w=vt[x][i];
if(w==fa) continue;
find_up(w,x);
for(int i=1;i<=k;i++)
up[x][i]+=up[w][i-1];
}
for(int i=0;i<=k;i++) up[x][i]+=p[x],all[x][i]=up[x][i];
}
void find_all(int x,int fa){
if(fa!=-1){
for(int i=1;i<=k;i++)
all[x][i]+=all[fa][i-1]-up[x][i-2];
}
for(int i=0;i<vt[x].size();i++){
int w=vt[x][i];
if(w==fa) continue;
find_all(w,x);
}
}
int main(){
int u,v,ans=0;
cin>>n>>k;
for(int i=1;i<n;i++){
cin>>u>>v;
vt[u].push_back(v);
vt[v].push_back(u);
}
for(int i=1;i<=n;i++) cin>>p[i];
find_up(1,-1);
find_all(1,-1);
for(int i=1;i<=n;i++) cout<<all[i][k]<<'\n';
return 0;
}
但是在 find_up
函数中,对于每一个节点 x
,连接它的每一条边都会被遍历一次,且遍历的同时还会有一个 k
次的 for
循环。
那是不是说这个代码的复杂度就是 O(nk)?
如果是的,那为什么暴力不能过?(从每一个节点延伸 k 次也是 O(nk) 的呀)如果蒟蒻的理解有误,请大佬们轻喷。
其次,在 find_up
函数中的 for
循环嵌套中两层循环变量都用的是 i
,一般来说编译器不是应该给个 Warning
什么之类的吗,但这次什么都没提示,等我交完才发现。难道又是什么隐藏bug?