1. 程式人生 > 實用技巧 >牛客nc210473 吉吉王國---二分答案+樹形dp

牛客nc210473 吉吉王國---二分答案+樹形dp

題目連結:https://ac.nowcoder.com/acm/problem/210473

簡單題意:刪去一些邊,使得葉子和根節點1不連通。求刪去的邊權和<=m的情況下,其中最大邊權的最小值

要求最小的最大值,考慮二分答案mid,然後用上一題的樹形dp來判斷最大值為mid的情況下,結果f[1]和m的關係即可。注意做樹形dp的時候如果邊權>mid就不能刪掉這個邊,只能刪掉子樹

#include<bits/stdc++.h>
#define pb push_back
using namespace std;

vector<int> g[1010];
int n,m,i,l,r,mid,d[1010][1010],vis[1010],f[1010];

void dp(int u){
    vis[u]=1; int num=0;
    for (int i=0;i<g[u].size();i++)
      if (!vis[g[u][i]]) num++;
    if (num==0) f[u]=1e6;
    for (int i=0;i<g[u].size();i++){
      int k=g[u][i]; 
	  if (vis[k]) continue;
	  dp(k);
      if (d[u][k]>mid) f[u]+=f[k]; else f[u]+=min(f[k],d[u][k]);
	}
}

int main(){
	cin>>n>>m;
	for (i=1;i<n;i++){
	  int x,y,dis;
	  cin>>x>>y>>dis;
	  g[x].pb(y);g[y].pb(x);
	  d[x][y]=d[y][x]=dis;
	}
	l=0;r=1e3+10;
	while (l<r-1){
	  memset(vis,0,sizeof(vis)); memset(f,0,sizeof(f));
	  mid=(l+r)/2; dp(1);
	  if (f[1]>m) l=mid; else r=mid;
	}
	if (r==1e3+10) cout<<-1<<endl; else cout<<r<<endl;
	return 0;
}