E1 - Weights Division (easy version)

E1 - Weights Division (easy version)

题意:给定一个带权无环联通图(编号为1的节点是这颗树的根),每一次可以选择一条边,将这条边的权值变成原来的1/2,向下取整。问:当根节点到所有叶子节点的距离的和小于等于题目要求的S时,最少操作次数是?

 

 AC_Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define endl '\n'
 5 const ll mod=1e9+7;
 6 const int maxn = 1e5+10;
 7 
 8 vector<ll>w,cnt;                     //w[i]表示i边的权值;  cnt[i]表示i边所影响的路径有几个
 9 vector<vector<pair<ll,ll>>>g;
10 
11 ll getdiff(ll i){                    //算i边缩小一半后对整个答案造成的影响
12     return w[i]*1ll*cnt[i]-(w[i]/2)*1ll*cnt[i];
13 }
14 
15 void dfs(ll v, ll fa=-1){           //fa表示v与它的父亲连的那条边的编号
16     if( g[v].size()==1 && fa!=-1 ){ //v是叶子节点
17         cnt[fa]=1;
18         return ;
19     }
20 
21     for( auto i: g[v] ){
22         if( i.second==fa ) continue;
23         dfs(i.first,i.second);
24         if( fa!=-1 ){
25             cnt[fa]+=cnt[i.second];
26         }
27     }
28 }
29 
30 ll n,s;
31 int main()
32 {
33     int t;cin>>t;
34     while( t-- ){
35         cin>>n>>s;
36         w = cnt = vector<ll>(n-1);
37         g = vector<vector<pair<ll,ll>>>(n+1);
38         for(int i=0;i<n-1;i++){
39             ll x,y; cin>>x>>y>>w[i];
40             g[x].push_back({y,i});  //存连接点和边的编号
41             g[y].push_back({x,i});
42         }
43 
44         dfs(1);                     //dfs一遍求出每个边所能影响的root-->leaves路径有多少条(也就是每个边对最后值的贡献是多少)
45 
46         set<pair<ll,ll>>st;         //set自动按getdiff的大小从小到大排序
47         ll cur=0;
48         for(int i=0;i<n-1;i++){     //预处理
49             st.insert({getdiff(i),i});
50             cur+=w[i]*1ll*cnt[i];
51         }
52 
53         ll ans=0;
54         while(cur>s){
55             int id=st.rbegin()->second; //rbegin:集合里的最后一个元素
56             st.erase(prev(st.end()));   //删除集合里的最后一个元素
57             cur-=getdiff(id);
58             w[id]/=2;
59             st.insert({getdiff(id),id});
60             ans++;
61         }
62         cout<<ans<<endl;
63     }
64     return 0;
65 }

 

posted @ 2020-08-08 17:21  swsyya  阅读(285)  评论(0编辑  收藏  举报

回到顶部