zoukankan      html  css  js  c++  java
  • E1

    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 '
    '
     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 }
  • 相关阅读:
    解决:只有 DBA 才能导入由其他 DBA 导出的文件
    查找—顺序查找
    软件测试,想说爱你不容易
    Oracle常用SQL
    排序—直接插入排序
    排序—归并排序
    排序—快速排序
    排序—选择排序
    查找—折半查找
    排序—堆排序
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13458587.html
Copyright © 2011-2022 走看看