给定一棵 N 个节点的树,每条边带有一个权值。
求一条简单路径,路径上各条边的权值和等于K,且路径包含的边的数量最少。
输入格式
第一行两个整数 N, K。
第2~N行每行三个整数x,y,z,表示一条无向边的两个端点x,y和权值z,点的编号从0开始。
输出格式
输出一个整数,表示最少边数量。
如果不存在满足要求的路径,输出-1。
数据范围
N≤200000,K≤1000000
输入样例:
4 3
0 1 1
1 2 2
1 3 4
输出样例:
2
题解:点分治
用数组记录经过当前根的路径长度一样时最少边数tmp
同时记得不能用memset会TLE。用递归O(N)初始化。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N=200005*5,K=1000005*5;
int tot,n,k,head[N],nex[N],ans=1e9,ver[N],val[N],d[N];
int v[N],tmp[K],size[N];
int pos,mine=1e9;
inline void add(int x,int y,int z){
nex[++tot]=head[x];head[x]=tot;ver[tot]=y;val[tot]=z;
}
inline int get_gravity(int x,int larg){
v[x]=1;size[x]=1;
int mm=0;
for(int i=head[x];i;i=nex[i]){
if(v[ver[i]])continue;
get_gravity(ver[i],larg);
mm=max(mm,size[ver[i]]);
size[x]+=size[ver[i]];
}
mm=max(mm,larg-size[x]);
if(mm<mine){
pos=x;mine=mm;
}
v[x]=0;
}
inline void tree_dfs_ask(int p,int cnt){
v[p]=1;
if(d[p]==k)ans=min(ans,cnt);
else if(d[p]<k){if(tmp[k-d[p]]!=0)
ans=min(ans,tmp[k-d[p]]+cnt);
}
for(int i=head[p];i;i=nex[i]){
int y=ver[i];
if(v[y])continue;
d[y]=d[p]+val[i];
tree_dfs_ask(y,cnt+1);
}
v[p]=0;
}
inline void tree_dfs_change(int p,int cnt){
v[p]=1;
if(d[p]<=k)tmp[d[p]]= tmp[d[p]]==0?cnt:min(cnt,tmp[d[p]]);
for(int i=head[p];i;i=nex[i]){
int y=ver[i];
if(v[y])continue;
d[y]=d[p]+val[i];
tree_dfs_change(y,cnt+1);
}
v[p]=0;
}
inline void clearing(int x){
if(d[x]<=k)tmp[d[x]]=0;
for(int i=head[x];i;i=nex[i]){
int y=ver[i];
if(v[y])continue;
v[y]=1;
d[y]=d[x]+val[i];
clearing(y);
v[y]=0;
}
}
inline void dfs(int p,int larg){
v[p]=1;
if(size[p]==1)return ;
for(int i=head[p];i;i=nex[i]){
int y=ver[i];
if(v[y])continue;
d[y]=val[i];
tree_dfs_ask(y,1);
tree_dfs_change(y,1);
}
d[p]=0;
clearing(p);
for(int i=head[p];i;i=nex[i]){
int y=ver[i];
if(v[y])continue;
mine=1e9;
get_gravity(y,size[y]);
mine=1e9;
get_gravity(pos,size[y]);
dfs(pos,size[pos]);
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>k;
for (int i=1; i<n; i++){
int x,y,z;
cin>>x>>y>>z;x+=1;y+=1;
add(x,y,z);add(y,x,z);
}
get_gravity(1,n);
get_gravity(pos,n);
dfs(pos,size[pos]);
if(ans==1e9)cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}
最后
以上就是怕孤单招牌最近收集整理的关于Acwing 264. 权值的全部内容,更多相关Acwing内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复