Codeforces Round #635 C. Linova and Kingdom

传送门:C. Linova and Kingdom

题意:给你一棵树,要求对k个结点涂色,然后统计每个未涂色结点到根结点的路径上未涂色结点的和,求和最大能为多少

题解:对着样例画几遍,然后贪心发现,最优解一定是当前结点的深度减去它的子结点个数大的来涂色,然后直接就建树进行dfs就行了,其实这道题可以作为一道模板题qwq(比赛没写出来主要还是不会建树(⊙﹏⊙)b)

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <stack>
 7 #include <queue>
 8 #include <vector>
 9 #include <map>
10 #include <set>
11 #include <unordered_set>
12 #include <unordered_map>
13 #define ll long long
14 #define fi first
15 #define se second
16 #define pb push_back
17 #define me memset
18 const int N = 1e6 + 10;
19 const int mod = 1e9 + 7;
20 using namespace std;
21 typedef pair<int,int> PII;
22 typedef pair<long,long> PLL;
23 
24 int n,k;
25 int u,v;
26 ll sum;
27 int pos[N],cnt[N];
28 vector<int> s[N];
29 vector<int> res;
30 
31 void dfs(int u,int pre){
32     pos[u]=pos[pre]+1;
33     cnt[u]=1;
34     vector<int>::iterator iter;
35     for(iter=s[u].begin();iter!=s[u].end();++iter){
36         if(*iter==pre) continue;
37         dfs(*iter,u);
38         cnt[u]+=cnt[*iter];
39     }
40     res.pb(pos[u]-cnt[u]);
41 }
42 
43 int main() {
44     ios::sync_with_stdio(false);
45     cin>>n>>k;
46     for(int i=1;i<n;++i){
47        cin>>u>>v;
48        s[u].pb(v);
49        s[v].pb(u);
50     }
51     dfs(1,0);
52     sort(res.begin(),res.end());
53     reverse(res.begin(),res.end());
54     for(int i=0;i<k;++i) sum+=(ll)res[i];
55     printf("%lld\n",sum);
56 
57 
58     return 0;
59 }
View Code

猜你喜欢

转载自www.cnblogs.com/lr599909928/p/12731967.html
今日推荐