题意:
一棵树,边权为1,根节点是:1,要标记 k 个节点,这k个节点,都要去1节点,问这k个节点去 1 节点,路过的没有被标记的节点的个数总和。
思路:
肯定选深的节点标记啊,这样每个标记的节点到1节点会多一点,但是…是要选k个节点,当叶子节点选完后,肯定选叶子节点的根节点标记,但这样访问的普通节点就会减1…(也不知道怎么往我那个方法上引…我是到这就直接想到的) 对每个点,他到 1 能访问的普通城市的数量是:深度减去他下面的所有节点的数量…
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e6+177;
vector<ll >ve;
int n,k;
struct Node{
int next;
int to;
int vul;
}edge[maxn];
int head[maxn];
int tot;
int dp[maxn];
void add(int from,int to,int vul){
edge[++tot].next=head[from];
edge[tot].to=to;
edge[tot].vul=vul;
head[from]=tot;
}
void init(){
memset(head,0,sizeof(head));
tot=0;
for(int i=0;i<=n;i++){
dp[i]=1;
}
}
void dfs(int x,int f,int df){
for(int i=head[x];i;i=edge[i].next){
int y=edge[i].to;
if(y==f){
continue;
}
dfs(y,x,df+1);
dp[x]=dp[x]+dp[y];
}
ve.push_back(df-(dp[x]-1));
}
int main(){
scanf("%d%d",&n,&k);
init();
int x,y;
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
add(x,y,1);
add(y,x,1);
}
dfs(1,-1,0);
ll ans=0;
sort(ve.begin(),ve.end());
for(int i=ve.size()-1;i>=ve.size()-k;i--){
ans=ans+ve[i];
}
cout<<ans<<endl;
}