题目分析
这道题wa了不知道多少次,状态转移方程非常好写,但是调bug调了一上午。首先我将程序中的INF设置的过大,导致了加的过程中爆INT,这个潜伏的bug找了好几个小时,真是蠢!!这道题主要思想是利用2分的思想,对于power limit进行2分搜索即可,同时需要注意有可能找不到值,那么需要特判输出-1.最初的时候忘了还有可能有这种情况了,别的就比较简单了,看了一下,这道题时那场多校比赛中可以说是最水的题了!!!写了这么久!!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1005;
const int INF = 1000005;
struct Edge{
int to,w,next;
}e[maxn<<1];
int head[maxn],dp[maxn],tot;
void addedge(int from, int to,int w){
e[tot].to = to;
e[tot].w = w;
e[tot].next = head[from];
head[from] = tot++;
}
void dfs(int u,int fa,int limit)
{
dp[u] = 0;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].to;
int w = e[i].w;
if(v != fa){
dfs(v, u, limit);
if(!dp[v]){
if(w > limit) dp[u] += INF;
else dp[u] += w;
}
else{
if(w > limit) dp[u] += dp[v];
else dp[u] += min(w, dp[v]);
}
}
}
}
void init(){
tot = 0;
memset(head, -1, sizeof(head));
memset(dp, 0, sizeof(dp));
}
int main(){
int n,m;
while(scanf("%d %d", &n, &m) != EOF){
if(!n && !m) break;
init();
int from,to,w,left = INF, right = 0;
for(int i = 1; i < n; i++){
scanf("%d%d%d", &from, &to, &w);
addedge(from, to, w);
addedge(to, from, w);
left = min(left, w);
right = max(right, w);
}
int temp = right;
while(left <= right){
int mid = (left + right)/2;
dfs(1, -1, mid);
if(dp[1] <= m) right = mid - 1;
else left = mid + 1;
}
if(left > temp) printf("-1\n");
else printf("%d\n", left);
}
return 0;
}