The 2019 ICPC Asia Shanghai Regional Contest---H Tree Partition 二分答案,从下往上切最大子树

Posted --hpy-7m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The 2019 ICPC Asia Shanghai Regional Contest---H Tree Partition 二分答案,从下往上切最大子树相关的知识,希望对你有一定的参考价值。

题意:https://ac.nowcoder.com/acm/contest/4370

将一棵树切k-1刀分成k棵树,问这k棵树里最大的权值的最小值是多少

思路:https://www.cnblogs.com/ucprer/p/11931263.html

二分最大值。

dfs割子树,每次从下往上切一个最大的树。

单个dfs表示保证当前节点可切,然后子树dfs完了,sort子树,选最大的切,直到当前u节点也可切

  1 #define ios ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr strcat
 13 #include <string>
 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 #include <cassert>
 21 #include <iomanip>
 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 25 //******************
 26 clock_t __START,__END;
 27 double __TOTALTIME;
 28 void _MS(){__START=clock();}
 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
 30 //***********************
 31 #define rint register int
 32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
 33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
 34 #define mem(a,b) memset(a,b,sizeof(a))
 35 #define pr printf
 36 #define sc scanf
 37 #define ls rt<<1
 38 #define rs rt<<1|1
 39 typedef pair<int,int> PII;
 40 typedef vector<int> VI;
 41 typedef unsigned long long ull;
 42 typedef long long ll;
 43 typedef double db;
 44 const db E=2.718281828;
 45 const db PI=acos(-1.0);
 46 const ll INF=(1LL<<60);
 47 const int inf=(1<<30);
 48 const db ESP=1e-9;
 49 const int mod=(int)1e9+7;
 50 const int N=(int)1e5+10;
 51 
 52 int n;
 53 ll val[N];
 54 ll _val[N];
 55 ll er[66];
 56 //=========================================================================================
 57 vector<vector<int> >G(N),GG(N);
 58 
 59 bool cmp(int a,int b)
 60 {
 61     return val[a]-_val[a]>val[b]-_val[b];
 62 }
 63 
 64 ll pre(int v,int u)
 65 {
 66     int sz=G[v].size();
 67     for(int i=0;i<sz;++i)
 68     {
 69         int to=G[v][i];
 70         if(to!=u)
 71         {
 72             GG[v].push_back(to);
 73             val[v]+=pre(to,v);
 74         }
 75     }
 76     return val[v];
 77 }
 78 
 79 ll st,max_;
 80 int cnt;
 81 
 82 void cut(int u,int fa)
 83 {
 84     if(val[u]-_val[u]<=st)return;
 85     int sz=G[u].size();
 86     for(int i=0;i<sz;++i)
 87     {
 88         if(val[u]-_val[u]<=st)return;
 89         int to=G[u][i];
 90         if(to!=fa)
 91             cut(to,u),_val[u]+=_val[to];
 92     }
 93     if(val[u]-_val[u]<=st)return;
 94     sort(GG[u].begin(),GG[u].end(),cmp);
 95     sz=GG[u].size();
 96     for(int i=0;i<sz;++i)
 97     {
 98         int to=GG[u][i];
 99         if(val[u]-_val[u]<=st)
100             return;
101         cnt++;
102         _val[u]+=val[to]-_val[to];
103     }
104 }
105 
106 ll get(int k)
107 {
108     st=er[50];
109     for(int i=50;i>=1;--i)
110     {
111         if(st-er[i]<max_)continue;
112         for(int j=0;j<=n;++j)_val[j]=0;
113         cnt=1;//根节点我手动切
114         st-=er[i];
115         cut(1,0);
116         if(cnt>k)
117             st+=er[i];
118     }
119     return st;
120 }
121 int TOT=0;
122 
123 void solve()
124 {
125     pr("Case #%d: ",++TOT);
126     int k;
127     sc("%d%d",&n,&k);
128     for(int i=1;i<=n;++i)G[i].clear(),GG[i].clear();
129     for(int i=1;i<n;++i)
130     {
131         int u,v;
132         sc("%d%d",&u,&v);
133         G[u].push_back(v);
134         G[v].push_back(u);
135     }
136     max_=0;
137     for(int i=1;i<=n;++i)sc("%lld",&val[i]),max_=max(max_,val[i]);
138     pre(1,0);
139     pr("%lld
",get(k));
140 }
141 
142 int main()
143 {
144     er[1]=1;
145     for(int i=2;i<=65;++i)er[i]=er[i-1]*2;//,pr("%d: %lld
",i,er[i]);
146     int T;
147     sc("%d",&T);
148     while(T--)solve();
149     return 0;
150 }
151 
152 /**************************************************************************************/

 

以上是关于The 2019 ICPC Asia Shanghai Regional Contest---H Tree Partition 二分答案,从下往上切最大子树的主要内容,如果未能解决你的问题,请参考以下文章

The Preliminary Contest for ICPC Asia Yinchuan 2019

The Preliminary Contest for ICPC Asia Shenyang 2019

The Preliminary Contest for ICPC Asia Shanghai 2019

The Preliminary Contest for ICPC Asia Shanghai 2019

The Preliminary Contest for ICPC Asia Xuzhou 2019

The Preliminary Contest for ICPC Asia Nanchang 2019