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