题面:
样例解释:
题目链接:
https://codeforces.com/contest/1337/problem/C
考察点:
贪心,DFS,树的深度
题目大意:
给一颗根为 1 的树,要在树的 k 个节点上建立工业城市,每个工业城市都有一个老大,然后工业城市的老大
都需要到 1 号节点聚会商量大事,在各个老大到 1 号节点的过程中可以建立 n - k 个旅游城市,工业城市
的老大经过 旅游城市时 价值 + 1,求一下所有工业老大到 根节点的路径中经过的旅游城市的最大值。
侃侃:
Code:
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define x first
#define y second
using namespace std;
const int maxn = 2e5 + 10;
typedef long long LL;
typedef pair<int,int>PII;
vector<int>G[maxn];
int size[maxn],vis[maxn];
int n,k;
int u,v;
struct node{
int x,y;
bool operator < (const node& a) const {
return x - y > a.x - a.y;
}
}P[maxn];
void DFS(int u,int fa) {
vis[u] = 1;
// 节点深度
P[u].y = P[fa].y + 1;
for(int i = 0; i < G[u].size(); i ++) {
int v = G[u][i];
if(vis[v]) continue;
DFS(v,u);
// 子节点大小
P[u].x += P[v].x + 1;
}
return ;
}
int main(void) {
scanf("%d%d",&n,&k);
for(int i = 1; i < n; i ++) {
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
// 深度应该从 0 开始,当然也可以从 1 开始,下面就需要 + 1
P[0].y = -1;
DFS(1,0);
sort(P + 1,P + 1 + n);
LL res = 0;
for(int i = 1; i <= n - k; i ++) {
res += P[i].x - P[i].y;
}
printf("%lld
",res);
return 0;
}
后记:
这道题考察的知识点还是不少的,不仅这样,还需要一点点的思维,抓住贪心的本质去解题,
可以达到事半功倍的效果。