题意

给你一颗有根树,你要选择\(k\)个点,最大化\(\sum_{i \in S} val_i\),其中\(S\)是被选点的集合,\(val_i\)等于节点\(i\)到根的路径上未被选择点的个数。

解题思路

这题思路挺有意思的。

我们可以逐个点进行选择。新选择一个点对答案的贡献为点到跟的距离减去子树中被选择点的个数。

这样子的话,很容易可以得出,如果点\(u\)在答案中,那么它所有的后代也必须在答案中。

由此,我们可以为每个点赋一个权值\(v_i = d_i - sub_i\),\(d_i\)表示点\(i\)到根的距离,\(sub_i\)表示点\(i\)后代的个数。

AC代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. // #include <ext/rope>
  4. // using namespace __gnu_cxx;
  5. // #include <ext/pb_ds/assoc_container.hpp>
  6. // #include <ext/pb_ds/tree_policy.hpp>
  7. // using namespace __gnu_pbds;
  8. // typedef ll key_type;
  9. // typedef null_mapped_type value_type;
  10. // typedef tree<key_type, value_type, less<key_type>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
  11. // typedef __gnu_pbds::priority_queue<pi,greater<pi>,pairing_heap_tag > heap;
  12. // mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  13. // int rnd(int l,int r){return l+rng()%(r-l+1);}
  14. typedef long long ll;
  15. typedef double db;
  16. typedef pair<int,int> PI;
  17. typedef vector<int> VI;
  18. #define rep(i,_,__) for (int i=_; i<=__; ++i)
  19. #define per(i,_,__) for (int i=_; i>= __; --i)
  20. #define pb push_back
  21. #define mp make_pair
  22. #define fi first
  23. #define se second
  24. #define x1 _x
  25. #define x2 __x
  26. #define y1 _y
  27. #define y2 __y
  28. #define SZ(x) ((int)(x).size())
  29. #define all(x) (x).begin(),(x).end()
  30. #define rall(x) (x).rbegin(),(x).rend()
  31. #define endl '\n'
  32. const double pi = acos(-1.0);
  33. namespace IO{
  34. bool REOF = 1; //为0表示文件结尾
  35. inline char nc() {
  36. static char buf[1 << 20], *p1 = buf, *p2 = buf;
  37. return p1 == p2 && REOF && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? (REOF = 0, EOF) : *p1++;
  38. }
  39. template<class T>
  40. inline bool read(T &x) {
  41. char c = nc();bool f = 0; x = 0;
  42. while (c<'0' || c>'9')c == '-' && (f = 1), c = nc();
  43. while (c >= '0'&&c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = nc();
  44. if(f)x=-x;
  45. return REOF;
  46. }
  47. template<class T>
  48. inline bool write(T x){
  49. if(x > 9) write(x / 10);
  50. putchar('0'+x%10);
  51. return REOF;
  52. }
  53. template<typename T, typename... T2>
  54. inline bool read(T &x, T2 &... rest) {
  55. read(x);
  56. return read(rest...);
  57. }
  58. inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')); }
  59. // inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || c==' '; }
  60. inline bool read_str(char *a) {
  61. while ((*a = nc()) && need(*a) && REOF)++a; *a = '\0';
  62. return REOF;
  63. }
  64. inline bool read_db(double &x){
  65. bool f = 0; char ch = nc(); x = 0;
  66. while(ch<'0'||ch>'9') {f|=(ch=='-');ch=nc();}
  67. while(ch>='0'&&ch<='9'){x=x*10.0+(ch^48);ch=nc();}
  68. if(ch == '.') {
  69. double tmp = 1; ch = nc();
  70. while(ch>='0'&&ch<='9'){tmp=tmp/10.0;x=x+tmp*(ch^48);ch=nc();}
  71. }
  72. if(f)x=-x;
  73. return REOF;
  74. }
  75. template<class TH>
  76. inline void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }
  77. template<class TH, class... TA>
  78. inline void _dbg(const char *sdbg, TH h, TA... a) {
  79. while(*sdbg!=',')cerr<<*sdbg++;
  80. cerr<<'='<<h<<','<<' '; _dbg(sdbg+1, a...);
  81. }
  82. template<class T>
  83. ostream &operator<<(ostream& os, vector<T> V) {
  84. os << "[ "; for (auto vv : V) os << vv << ","; return os << " ]";
  85. }
  86. template<class T>
  87. ostream &operator<<(ostream& os, set<T> V) {
  88. os << "[ "; for (auto vv : V) os << vv << ","; return os << " ]";
  89. }
  90. template<class T>
  91. ostream &operator<<(ostream& os, map<T,T> V) {
  92. os << "[ "; for (auto vv : V) os << vv << ","; return os << " ]";
  93. }
  94. template<class L, class R>
  95. ostream &operator<<(ostream &os, pair<L,R> P) {
  96. return os << "(" << P.x << "," << P.y << ")";
  97. }
  98. #ifdef BACKLIGHT
  99. #define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
  100. #else
  101. #define debug(...)
  102. #endif
  103. }
  104. using namespace IO;
  105. const int N = 2e5 + 5;
  106. const int M = 2e5 + 5;
  107. const int MAXV = 1e6 + 5;
  108. const int MOD = 1e9+7; // 998244353 1e9+7
  109. const int INF = 0x3f3f3f3f; // 1e9+7 0x3f3f3f3f
  110. const ll LLINF = 0x3f3f3f3f3f3f3f3f; // 1e18+9 0x3f3f3f3f3f3f3f3f
  111. const double eps = 1e-8;
  112. // int dx[4] = { 0, 1, 0, -1 };
  113. // int dx[8] = { 1, 0, -1, 1, -1, 1, 0, -1 };
  114. // int dy[4] = { 1, 0, -1, 0 };
  115. // int dy[8] = { 1, 1, 1, 0, 0, -1, -1, -1 };
  116. // ll qp(ll a, ll b) {
  117. // ll res = 1;
  118. // a %= mod;
  119. // assert(b >= 0);
  120. // while(b){
  121. // if(b&1)
  122. // res = res * a % mod;
  123. // a = a * a % mod;
  124. // b >>= 1;
  125. // }
  126. // return res;
  127. // }
  128. // ll inv(ll x) {return qp(x, mod - 2);}
  129. // ll factor[N], finv[N];
  130. // void init() {
  131. // factor[0]=1;
  132. // for(int i=1; i<N; i++) factor[i] = factor[i-1] * i % mod;
  133. // finv[N-1] = qp(factor[N-1], mod - 2);
  134. // for(int i=N-2; i>=0; i--) finv[i] = finv[i+1] * (i+1) % mod;
  135. // }
  136. // ll c(ll n, ll m) {
  137. // return factor[n] * finv[m] % mod * finv[n-m] % mod;
  138. // }
  139. // #define ls (x<<1)
  140. // #define rs (x<<1|1)
  141. // #define mid ((l+r)>>1)
  142. // #define lson ls,l,mid
  143. // #define rson rs,mid+1,r
  144. #define fore(_, __) for(int _ = head[__]; _; _=e[_].nxt)
  145. int head[N], tot = 1;
  146. struct Edge {
  147. int v, nxt;
  148. Edge(){}
  149. Edge(int _v, int _nxt):v(_v), nxt(_nxt) {}
  150. }e[N << 1];
  151. void addedge(int u, int v) {
  152. e[tot] = Edge(v, head[u]); head[u] = tot++;
  153. e[tot] = Edge(u, head[v]); head[v] = tot++;
  154. }
  155. /**
  156. * ********** Backlight **********
  157. * 仔细读题
  158. * 注意边界条件
  159. * 记得注释输入流重定向
  160. * 没有思路就试试逆向思维
  161. * 我不打了,能不能把我的分还给我
  162. */
  163. int d[N], sz[N];
  164. void dfs(int u, int f) {
  165. d[u] = d[f] + 1;
  166. sz[u] = 1;
  167. fore(i, u) {
  168. int v = e[i].v;
  169. if(v==f)continue;
  170. dfs(v, u);
  171. sz[u] += sz[v];
  172. }
  173. }
  174. int n, k, a[N];
  175. void solve(int Case) {
  176. read(n, k);
  177. int u, v;
  178. rep(i, 1, n-1) {
  179. read(u, v);
  180. addedge(u, v);
  181. }
  182. dfs(1, 0);
  183. rep(i, 1, n) a[i] = d[i] - sz[i];
  184. sort(a+1, a+1+n);
  185. ll ans = 0;
  186. rep(i, 1, k) ans += (ll)a[n-i+1];
  187. printf("%lld\n", ans);
  188. }
  189. int main()
  190. {
  191. #ifdef BACKLIGHT
  192. freopen("in.txt", "r", stdin);
  193. #endif
  194. // ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  195. // int _T; read(_T); for (int _ = 1; _ <= _T; _++) solve(_);
  196. // int _T=1; while(read(n)) solve(_T), _T++;
  197. solve(1);
  198. return 0;
  199. }

Codeforces 1337C Linova and Kingdom的更多相关文章

  1. Codeforces Round #635C Linova and Kingdom 思维

    Linova and Kingdom 题意 现在有一颗n个节点的树,每个节点是一个城市,现在要选出k个城市作为工业城市,其他城市作为旅游城市,现在每个工业城市要派出一名特使前往根节点,每个特使的幸福度 ...

  2. Codeforces Round #635 C. Linova and Kingdom

    传送门:C. Linova and Kingdom 题意:给你一棵树,要求对k个结点涂色,然后统计每个未涂色结点到根结点的路径上未涂色结点的和,求和最大能为多少 题解:对着样例画几遍,然后贪心发现,最 ...

  3. codeforces:Roads in the Kingdom分析和实现

    题目大意:国家有n个城市,还有n条道路,每条道路连通两个不同的城市,n条道路使得所有n个城市相互连通.现在国家经费不足,要关闭一条道路.国家的不便度定义为国家中任意两个不同的城市之间的距离的最大值,那 ...

  4. CodeForces - 115E:Linear Kingdom Races (DP+线段树+lazy)

    pro: 从左到有有N个车道,都有一定程度损坏,所以有不同的修理费a[]: 有M场比赛,每场比赛的场地是[Li,Ri],即如果这个区间的车道都被修理好,则可以举办这个比赛,并且收益是Pi.问最多得到多 ...

  5. Linova and Kingdom(树型-贪心)

    题目大意:给定一棵树,1为首都(首都可以是工业城市也可以是旅游城市),一共有n个点. 其中要选出k个工业城市,每个工业城市出一个代表去首都,其快乐值是其途径旅游城市(非工业)的个数 求所有快乐值相加的 ...

  6. CF1336 Linova and Kingdom

    题面 给定 n 个节点的有根树,根是 1 号节点. 你可以选择 k 个节点将其设置为工业城市,其余设置为旅游城市. 对于一个工业城市,定义它的幸福值为工业城市到根的路径经过的旅游城市的数量. 你需要求 ...

  7. Codeforces Round #635 (Div. 2) 题解

    渭城朝雨浥轻尘,客舍青青柳色新. 劝君更尽一杯酒,西出阳关无故人.--王维 A. Ichihime and Triangle 网址:https://codeforces.com/contest/133 ...

  8. Codeforces Round #635 (Div. 2)

    Contest Info Practice Link Solved A B C D E F 4/6 O O Ø  Ø     O 在比赛中通过 Ø 赛后通过 ! 尝试了但是失败了 - 没有尝试 Sol ...

  9. Codeforces Round #635 (Div. 2)部分(A~E)题解

    虽然打的是div1,但最后半小时完全处于挂机状态,不会做1C,只有个 \(O(n^3)\) 的想法,水了水论坛,甚至看了一下div2的AB,所以干脆顺便写个div2的题解吧,内容看上去还丰富一些(X) ...

随机推荐

  1. OAuth2.0-4整合网关

    .antMatchers("/**").access("#oauth2.hasScope('scope1')")上面这行代码,只是控制大范围的访问权限,具体到方 ...

  2. 最受欢迎的 15 大 Python 库(2017)

    核心库 1. NumPy (提交数: 15980, 贡献者数: 522) 当开始处理Python中的科学任务,Python的SciPy Stack肯定可以提供帮助,它是专门为Python中科学计算而设 ...

  3. Nginx安装与运行配置总结

    Nginx安装与运行配置总结 1. 去官网下载对应的nginx包,推荐使用稳定版本 2. 上传nginx到linux系统 3. 安装依赖环境 (1)安装gcc环境 yun install gcc-c+ ...

  4. C#LeetCode刷题之#599-两个列表的最小索引总和​​​​​​​​​​​​​​(Minimum Index Sum of Two Lists)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3802 访问. 假设Andy和Doris想在晚餐时选择一家餐厅,并 ...

  5. LeetCode 931. 下降路径最小和 详解

    题目详情 给定一个方形整数数组 A,我们想要得到通过 A 的下降路径的最小和. 下降路径可以从第一行中的任何元素开始,并从每一行中选择一个元素.在下一行选择的元素和当前行所选元素最多相隔一列. 示例: ...

  6. jQuery的事件与 动画

    什么是事件: 事件的本质是委托. Jquery的 方法: $().css(); $().click(); 等等. 鼠标的事件: 区别在于:mouseover与mouseout再进入或离开后会执行这两个 ...

  7. MetadataCache更新

    MetadataCache什么时候更新 updateCache方法用来更新缓存的. 发起线程 controller-event-thread controller选举的时候 CLASS_NAME ME ...

  8. 快速排序&&归并排序

    快速排序 快速排序采用的是分治的策略,算法的具体实现过程是 1.确定一个数X(一般是选中间值X=q[l+r>>1]) 2.利用指针i,j,将数组中比X小的数放在一边,比X大的数放在另一边 ...

  9. unity探索者之微信支付,非第三方插件

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/8404604.html 相比微信的登录和分享功能,微信支付sdk的接入显得相当简单, ...

  10. VUE数据更新视图不更新的原因

    当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue当你修改数组的长度时,例如:vm.items.length = newLength 数组更新只能通过 ...