链接:https://ac.nowcoder.com/acm/contest/560/I
来源:牛客网
题目描述
You have a tree with N nodes and N-1 edges. Each node has a weight. The i-th node's weight is Wi.
Now you should divide the N nodes into K connected parts . Each part has at least one node.
The sum of all node's Wi in a part is X. The minimum X of all parts is Y. You need to calculate maximum Y.
输入描述:
The first line contains two integers N and K(1≤K≤N≤100000)
链接:https://ac.nowcoder.com/acm/contest/560/I
来源:牛客网
示例1
输入
复制
5 3 1 2 1 3 2 4 2 5 1 2 3 4 5
输出
复制
4
题意:把一个树分成k部分,每一部分权值相加,让最小值最大,输出最小值
题解:二分答案,节点u累计的权值符合条件时,就吧这一部分截下来
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,k;
ll mid;
vector<int> v[N];
ll dp[N];
int flag;
int val[N];
void dfs(int u,int fa)
{
dp[u]=val[u];
for(int i=0;i<v[u].size();i++)
{
int to=v[u][i];
if(to==fa) continue;
dfs(to,u);
dp[u]+=dp[to];
}
// cout<<u<<" "<<dp[u]<<" "<<mid<<endl;
if(dp[u]>=mid)
{
dp[u]=0;
flag++;
}
}
int main()
{
scanf("%d%d",&n,&k);
int x,y;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
ll l=1,r=1e10;
ll ans=0;
while(l<=r)
{
mid=(r+l)>>1;
flag=0;
dfs(1,0);
if(flag>=k)
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans<<endl;
return 0;
}