震惊!史无前例的离奇错误!
查看原帖
震惊!史无前例的离奇错误!
186045
itisover楼主2021/10/5 22:50

注:窝是标题党,但是窝已经随机生成排了10w组了,但还是没找到QnQ,哭了/kk

第7个点比答案多 11

发现这题和点分治1差不多,多记每个点到根节点的边数,只用在双指针查找的时候顺带维护一下距离等于 kk 的路径的边数就好了

只有双指针加了几行,其他的和点分治1没区别

求hack原理或者哪里写丑了

#include<bits/stdc++.h>
using namespace std;
template <class T>
inline T read(){
    T r=0,f=0;char c=getchar();
    while(!isdigit(c)) f|=c=='-',c=getchar();
    while(isdigit(c)) r=(r<<3)+(r<<1)+(c^48),c=getchar();
    return f?-r:r;
}
const int N=2e5+5,INF=1e9;
int n,k;
struct zfz{
    int id,val,sum;
    bool operator <(const zfz x)const{return val<x.val;}
}f[N];
int vis[N],type[N],cnt;
int flag,ans=INF;
int rootsum,sum,root,sz[N];
int hd[N],nx[N<<1],to[N<<1],val[N<<1],tote;
void adde(int u,int v,int c){
    nx[++tote]=hd[u];to[tote]=v;val[tote]=c;hd[u]=tote;
    nx[++tote]=hd[v];to[tote]=u;val[tote]=c;hd[v]=tote;
}
void findroot(int u,int father){
    int maxx=0;sz[u]=1;
    for(int i=hd[u];i;i=nx[i]){
        int v=to[i];
        if(v==father||vis[v]) continue;
        findroot(v,u);
        sz[u]+=sz[v],maxx=max(maxx,sz[v]);
    }
    maxx=max(maxx,sum-sz[u]);
    if(rootsum>maxx) root=u,rootsum=maxx;
}
void dfs(int u,int father,int dis,int sub,int sum){
    if(dis<=k) f[++cnt]=(zfz){u,dis,sum},type[u]=sub;
    for(int i=hd[u];i;i=nx[i]){
        int v=to[i];
        if(v==father||vis[v]) continue;
        dfs(v,u,dis+val[i],sub,sum+1);
    }
}
void calc(int u){
    cnt=0;
    f[++cnt]=(zfz){u,0,0},type[u]=u;
    for(int i=hd[u];i;i=nx[i]){
        int v=to[i];
        if(vis[v]) continue;
        dfs(v,u,val[i],v,1);
    }
    sort(f+1,f+1+cnt);
    int l=1,r=cnt;
    while(l<r){
        if(f[l].val+f[r].val>k) --r;
        else{
            if(f[l].val+f[r].val<k) ++l;
            else{
                if(type[f[l].id]==type[f[r].id]){
                    if(f[r].val==f[r-1].val) --r;
                    else ++l;
                }
                else{
                    flag=1,ans=min(ans,f[l].sum+f[r].sum);
                    if(f[r].val==f[r-1].val) --r;
                    else ++l;
                }
            }
        }
    }
}
void solve(int u){
    vis[u]=1;calc(u);
    for(int i=hd[u];i;i=nx[i]){
        int v=to[i];
        if(vis[v]) continue;
        rootsum=n,sum=sz[v],findroot(v,u);
        solve(root);
    }
}
int main(){
    n=read<int>(),k=read<int>();
    for(int i=1;i<n;++i){
        int x=read<int>()+1,y=read<int>()+1,z=read<int>();
        adde(x,y,z);
    }
    rootsum=sum=n;
    findroot(1,0);
    solve(root);
    if(!flag) puts("-1");
    else printf("%d",ans);
    return 0;
}
2021/10/5 22:50
加载中...