题目
题意: 根节点为1的一棵树,删除一些边使叶子节点都不能到达根节点,并且边权和不能大于M,使删除边的最大值最小,并输出这个最大值。 没有删边方案输出-1.
注意INF不要开太大。每次叠加会爆int。很水的一题。
#include<cstdio>
#include<iostream>
#include<cstring>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=1e3+5,INF=1e6+1;
struct Edge{int to,nex,len;}edge[N<<1];int head[N],tot;
inline void add(int from,int to,int len){
edge[++tot]=(Edge){to,head[from],len},head[from]=tot;
edge[++tot]=(Edge){from,head[to],len},head[to]=tot;
}
int dp[N],n,m;
void dfs(int x,int fa,int lim){
int flag=0;
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].to,w=edge[i].len;
if(y==fa) continue;
flag=1,dfs(y,x,lim);
if(w>lim) dp[x]+=dp[y];
else dp[x]+=min(dp[y],w);
}
if(!flag) dp[x]=INF;
}
int check(int mid){
m(dp,0),dfs(1,1,mid);
return dp[1]<=m;
}
int main(){
while(~scanf("%d%d",&n,&m),n||m){
m(head,0),tot=0;
int mi=INF,mx=-INF;
for(int i=1,x,y,w;i<n;++i)
scanf("%d%d%d",&x,&y,&w),add(x,y,w),mi=min(mi,w),mx=max(mx,w);
int low=mi,high=mx,mid,ans=-1;
while(low<=high){
mid=(low+high)>>1;
if(check(mid)) {ans=mid,high=mid-1;}
else low=mid+1;
}
printf("%d\n",ans);
}
}