原题:P4178
写完后本来想试一下样例就莫名 RE,结果在第 50 行、第 67 行,这两行随便加其中一行上去就直接 RE,但是加上第 56 行就能正常跑。
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define lowbit(x) (x&(-x))
const int N=4e4+4;
struct edge{int to,ne,wv;}e[N*2];
int d[N],h[N],vis[N],t[N],siz[N],maxsiz[N],idx=0;
int n,k,num=0,ans=0;
vector<int> vec,clea;
queue<int> q;
void add(int a,int b,int c){
e[++idx]={b,h[a],c}; h[a]=idx;
}
int val,Siz;
void update(int x){
for(;x<=k;x+=lowbit(x)){
if(!t[x]) clea.push_back(x);
++t[x];
}
}
int query(int x){
int res=0;
for(;x;x-=lowbit(x)) res+=t[x];
return res;
}
void find(int u,int fa,int sum){
siz[u]=1;
maxsiz[u]=0;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if(vis[v]||v==fa) continue;
find(v,u,sum);
siz[u]+=siz[v];
maxsiz[u]=max(maxsiz[u],siz[v]);
}
maxsiz[u]=max(maxsiz[u],sum-siz[u]);
if(maxsiz[u]<Siz) Siz=maxsiz[u],val=u;
}
int how(int u,int fa){
int res=1;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if(vis[v]||fa==v) continue;
res+=how(v,u);
}
return res;
}
void dfs(int u,int fa){
// vec.push_back(u);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].to,w=e[i].wv;
if(vis[v]||v==fa) continue;
d[v]=d[u]+w;
if(d[v]>k) continue;
vec.push_back(v);
dfs(v,u);
}
}
void sol(int u){
vis[u]=1;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].to;
if(vis[v]) continue;
d[v]=e[i].wv;
dfs(v,u);
// vec.push_back(v);
for(int p:vec){
if(d[p]^k) ans+=query(k-d[p]);
else ans+=num;
}
for(int p:vec){
if(d[p]) update(d[p]);
else num++;
}
vec.clear();
}
num=0;
for(int p:clea) t[p]=0;
clea.clear();
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;++i){
int u,v,w; scanf("%d%d%d",&u,&v,&w);
add(u,v,w); add(v,u,w);
}
Siz=1e9; find(1,0,n);
sol(val); q.push(val);
printf("%d %d\n",val,n);
while(!q.empty()){
int x=q.front(); q.pop();
for(int i=h[x];i;i=e[i].ne){
int y=e[i].to;
if(vis[y]) continue;
int S=how(y,0);
Siz=1e9; find(y,0,S);
printf("%d %d\n",val,S);
sol(val); q.push(val);
}
}
printf("%d\n",ans);
}