求一棵树上路径长度刚好等于k的两点间的最小边数.如果不存在输出-1.
点分治不一定要容斥!!!!重要的事情要说三遍!
显然这题是点分治.
我们考虑 dp d p 搞,用 sum s u m 数组处理路径长度为 dis d i s 的两点间的最小边数,如果不存在为 inf i n f .
用ans=min(ans,sum[k-dis[u]]+d[u])
进行转移.
每一次 solve s o l v e 某个点之后暴力把没有处理过的点的 sum[dis] s u m [ d i s ] 都直接赋值为 inf i n f .
最后注意每一次把 sum[0] s u m [ 0 ] 赋值为 0 0 即可.
#include //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
#define int ll
const int yuzu=2e6,mulu=1e7,inf=0x3f3f3f3f;
typedef int fuko[yuzu|10];
struct edge{int to,cost;};
vector lj[yuzu|10];
fuko sz,mxs,vis,d,dis;
int n,k,rt,nsz,xiao,ans=inf,sum[mulu|10];
/*建议把数组大小开大10倍.*/
void grt(int u,int fa){
sz[u]=1,mxs[u]=0;
for (edge i:lj[u]){
int v=i.to,c=i.cost;
if (!vis[v]&&v^fa){
grt(v,u),sz[u]+=sz[v];
mxs[u]=max(mxs[u],sz[v]);
}
}
mxs[u]=max(mxs[u],nsz-mxs[u]);
if (mxs[u]void gdp(int u,int fa,int dep,int dist){
d[u]=dep,dis[u]=dist;
if (dis[u]>k) return;//不加这个剪枝会爆栈RE.
ans=min(ans,sum[k-dis[u]]+d[u]);
for (edge i:lj[u]){
int v=i.to,c=i.cost;
if (v^fa&&!vis[v]) gdp(v,u,dep+1,dist+c);
}
}
void dfs(int u,int fa,bool nico){
sum[dis[u]]=nico?min(sum[dis[u]],d[u]):inf;
for (edge i:lj[u]){
int v=i.to;
if (!vis[v]&&v^fa) dfs(v,u,nico);
}
}
#define init(x) rt=0,nsz=x,xiao=inf
void solve(int u){
vis[u]=1,sum[0]=0;
for (edge i:lj[u]){
int v=i.to;
if (!vis[v]){
gdp(v,0,1,i.cost);//get的时候不要忘记从u到v的这条边.
dfs(v,0,true);
}
}
for (edge i:lj[u]){
int v=i.to;
if (!vis[v]) dfs(v,0,false);
}
for (edge i:lj[u]){
int v=i.to,c=i.cost;
if (!vis[v]){
init(sz[v]),grt(v,0);
solve(rt);
}
}
}
main(){
int i,j;n=read(),k=read();
for (i=1;iint u=read()+1,v=read()+1,c=read();//注意点从0开始编号.
lj[u].push_back(edge{v,c});
lj[v].push_back(edge{u,c});
}
fill(sum+1,sum+mulu+1,inf);
init(n),grt(1,0),solve(rt);
write(ans^inf?ans:-1);
}
/*
4 3
0 1 1
1 2 2
1 3 4
*/