以下代码在洛谷最大点 500ms 通过了,校内 OJ 跑了 4700ms ,我不确定是否是校内 OJ 效率问题,因此询问一下。配有完整代码解释。
bool cmp(int x,int y){return dfn[x] < dfn[y];}
void buildvtree(){
tot = 0;
sort(q.begin(),q.end(),cmp);//q里面是关键点,cmp排序逻辑是按照dfn从小到大
for(int i = 0;i < q.size();i ++){
id[++ tot] = q[i];//id存的是虚树内的点
if(i + 1 < q.size())id[++ tot] = lca(q[i],q[i + 1]);//将相邻dfn的点的lca加入
}
sort(id + 1,id + tot + 1,cmp);//同上
tot = unique(id + 1,id + tot + 1) - id - 1;//去重
rep(i,1,tot - 1){
int lcaa = lca(id[i],id[i + 1]);
e2.add(lcaa,id[i + 1],dis[lcaa] + dis[id[i + 1]]);//该边权没有意义,将相邻点的lca与dfn较大的点连边
e2.add(id[i + 1],lcaa,dis[lcaa] + dis[id[i + 1]]);
used.push_back(lcaa);used.push_back(id[i + 1]);//记录用过的点,后面清空
}
}
以及清空部分
e2.cnt = 0;
for(int v : q){
bk[v] = false;
e2.head[v] = 0;
dp[v] = 0;
}
for(int v : used)e2.head[v] = 0;
used.clear();
e2.head[1] = 0;