E1. Weights Division (easy version)

E1 - Weights Division (easy version)

思路

d f s dfs 求出每个边的边权和经过每条边的次数。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(case, x) cout << case << "  : " << x << endl
#define open freopen("ii.txt", "r", stdin)
#define close freopen("oo.txt", "w", stdout)
#define IO                       \
ios::sync_with_stdio(false); \
cin.tie(0);                  \
cout.tie(0)
#define pb push_back
using namespace std;
#define int long long
#define lson rt << 1
#define rson rt << 1 | 1
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<long long, long long> PII;
const int maxn = 1e6 + 10;
struct edge{
int v,w;
};

vector<vector<edge>>G;
vector<int>val, cnt;

void dfs(int u, int fa = -1) {
if(fa!=-1&&G[u].size()==1)
cnt[u]=1;
for(auto t : G[u]) {
if(t.v == fa)continue;
val[t.v]=t.w;
dfs(t.v, u);
cnt[u] += cnt[t.v];
}
}

struct node{
int cnt,val;
bool operator<(const node t)const{
return val*cnt-(val/2)*cnt<t.val*t.cnt-(t.val/2)*t.cnt;
}
};
void solve() {
int n, s;
cin >> n >> s;
G = vector<vector<edge>>(n + 1);
cnt = val = vector<int>(n + 1);
for(int i = 0; i < n-1; ++i) {
int v, u, w;
cin >> v >> u >> w;
G[v].push_back({u, w});
G[u].push_back({v, w});
}
dfs(1, -1);
priority_queue<node>q;
int sum=0;
for(int i=2;i<=n;++i){
sum+=cnt[i]*val[i];
q.push({cnt[i],val[i]});
}
int ans=0;
while(sum > s) {
++ans; node now=q.top(); q.pop();
sum-=now.val*now.cnt-(now.val/2)*now.cnt;
q.push({now.cnt,now.val/2});
}
cout<<ans<<endl;
}

signed main() {
int t;
cin >> t;
while(t--) {
solve();
}

}