E1. Weights Division (easy version)
阿新 • • 發佈:2020-08-06
E1 - Weights Division (easy version)
題意
給你n個點和最高費用S,然後給你n-1條邊,和每條邊的邊權。讓你求如果可以\(w_i:=\frac{w_i}{2}\),需要最少多少步可以滿足\(cost\leq 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(); } }