P4149 [IOI2011] Race——点分治 模板
[IOI2011] Race
题目描述
给一棵树,每条边有权。求一条简单路径,权值和等于 \(k\),且边的数量最小。
输入格式
第一行包含两个整数 \(n,k\),表示树的大小与要求找到的路径的边权和。
接下来 \(n-1\) 行,每行三个整数 \(u_i,v_i,w_i\),代表有一条连接 \(u_i\) 与 \(v_i\),边权为 \(w_i\) 的无向边。
注意:点从 \(0\) 开始编号。
输出格式
输出一个整数,表示最小边数量。
如果不存在这样的路径,输出 \(-1\)。
样例 #1
样例输入 #1
4 3 0 1 1 1 2 2 1 3 4
样例输出 #1
2
提示
对于 \(100\%\) 的数据,保证 \(1\leq n\leq 2\times10^5\),\(0\leq k,w_i\leq 10^6\),\(0\leq u_i,v_i<n\)。
codes
#include<bits/stdc++.h> using namespace std; const int N=2e5+100; const int INF=1e6+100; struct edge { int y,n,z; }e[N<<1]; int n,m,head[N],cnt; int siz[N],root,all,mxa[N]; int qu[N],bi[N],uq[N],tot[INF],ed[N],ans=INF; bool vis[N]; long long dis[N]; void ad(int x,int y,int z) { e[++cnt].n=head[x]; e[cnt].y=y; e[cnt].z=z; head[x]=cnt; } void getrt(int u,int fa) { siz[u]=1;mxa[u]=0; for(int i=head[u];i;i=e[i].n) { int v=e[i].y; if(v==fa || vis[v])continue; getrt(v,u); siz[u]+=siz[v]; mxa[u]=max(mxa[u],siz[v]); } mxa[u]=max(all-siz[u],mxa[u]); if(mxa[u]<mxa[root])root=u; } void getdis(int u,int fa,int d) { if(dis[u]<=m) { qu[++qu[0]]=dis[u]; bi[qu[0]]=d; } for(int i=head[u];i;i=e[i].n) { int v=e[i].y; if(v==fa || vis[v])continue; dis[v]=dis[u]+e[i].z; getdis(v,u,d+1); } } void calc(int u) { int num=0; for(int i=head[u];i;i=e[i].n) { int v=e[i].y; if(vis[v])continue; qu[0]=0; dis[v]=e[i].z; getdis(v,0,1); for(int j=1;j<=qu[0];++j) if(qu[j]<=m) ans=min(tot[m-qu[j]]+bi[j],ans); for(int j=1;j<=qu[0];++j) { ++num; uq[num]=qu[j]; tot[qu[j]]=min(tot[qu[j]],bi[j]); } } for(int i=1;i<=num;++i) tot[uq[i]]=INF; } void solve(int nw) { vis[nw]=1; calc(nw); for(int i=head[nw];i;i=e[i].n) { int v=e[i].y; if(vis[v])continue; root=0; mxa[root]=INF; all=siz[v]; getrt(v,0); solve(root); } } void init() { scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<n;++i) { scanf("%d%d%d",&x,&y,&z); ++x;++y; ad(x,y,z);ad(y,x,z); } for(int i=1;i<=m;++i) tot[i]=INF; } void work() { all=n; mxa[root]=INF; getrt(1,0); solve(root); if(ans==INF)cout<<-1; else cout<<ans; } int main() { init(); work(); return 0; }
本文来自博客园,作者:Glowingfire,转载请注明原文链接:https://www.cnblogs.com/Glowingfire/p/18528964
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步