点分治45pts,求调
查看原帖
点分治45pts,求调
749175
114514xxx楼主2025/1/24 09:43
#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#pragma GCC optimize(3)
#pragma GCC optimize("inline")
using namespace std;
const int N=6e5+25;
const int inf=2e9+25;
struct Edge{
    int to,next,w;
}edge[N];
int head[N],cnt,n,k;
int siz[N],dp[N],tot,root;
int rem[N],dis[N],dep[N],q[N];
int ans=inf;
int mp[N*50];
map<int,int>cntp;
bitset<N>vis;
inline void add(int x,int y,int z){
    edge[++cnt].to=y;
    edge[cnt].next=head[x];
    edge[cnt].w=z;
    head[x]=cnt;
}
inline void getroot(int u,int fa){
    siz[u]=1,dp[u]=0;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v]||v==fa)continue;
        getroot(v,u);
        siz[u]+=siz[v];
        dp[u]=max(dp[u],siz[v]);
    }
    dp[u]=max(dp[u],tot-dp[u]);
    if(dp[u]<dp[root])root=u;
}
inline void getdis(int u,int fa){
    rem[++rem[0]]=dis[u];
    dep[u]=dep[fa]+1;
    cntp[rem[0]]=dep[u];
    if(dep[u]>ans||dis[u]>k)return;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa||vis[v])continue;
        dis[v]=dis[u]+edge[i].w;
        getdis(v,u);
    }
}
inline void calc(int u){
    int p=0;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v])continue;
        dep[v]=1;rem[0]=0;
        dis[v]=edge[i].w;
        getdis(v,0);
        for(int j=1;j<=rem[0];j++){
            ans=min(ans,cntp[j]+mp[k-rem[j]]);
        }
        for(int j=1;j<=rem[0];j++)
            mp[rem[j]]=min(mp[rem[j]],cntp[j]);
        for(int j=1;j<=rem[0];j++)
            q[++p]=rem[j],cntp[j]=0;
    }
    for(int i=1;i<=p;i++)
        mp[q[i]]=inf;
}
inline void solve(int u){
    vis[u]=1,calc(u);
    mp[0]=0;
    for(int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v])continue;
        dp[root=0]=N*10;
        tot=siz[v];
        getroot(v,u);
        solve(root);
    }
}
int main(){
    //freopen("P4149_3.in","r",stdin);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>k;
    int x,y,z;
    for(int i=1;i<n;i++){
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }
    tot=dp[root]=n;
    getroot(1,0);
    memset(mp,63,sizeof(mp));
    solve(root);
    //if(ans!=inf)cout<<ans;
    if(ans>n)cout<<-1;
    else cout<<ans;
   // else cout<<-1;
}

2025/1/24 09:43
加载中...