Problem Description
There is a tree having N vertices. In the tree there are K monkeys (K <= N). A vertex can be occupied by at most one monkey. They want to remove some edges and leave minimum edges, but each monkey must be connected to at least one other monkey through the remaining edges.
Print the minimum possible number of remaining edges.
Print the minimum possible number of remaining edges.
Input
The first line contains an integer T (1 <= T <= 100), the number of test cases.
Each test case begins with a line containing two integers N and K (2 <= K <= N <= 100000). The second line contains N-1 space-separated integers a1,a2,…,aN−1 , it means that there is an edge between vertex ai and vertex i+1 (1 <= ai <= i).
Each test case begins with a line containing two integers N and K (2 <= K <= N <= 100000). The second line contains N-1 space-separated integers a1,a2,…,aN−1 , it means that there is an edge between vertex ai and vertex i+1 (1 <= ai <= i).
Output
For each test case, print the minimum possible number of remaining edges.
Sample Input
2 4 4 1 2 3 4 3 1 1 1
Sample Output
2 2
题意:
给你一棵n节点的树,现在让你放k个猴子,可以删边,问最少可以剩余几条边,放k个猴子,满足任意一个猴
子至少与一只猴子相连。2<=k<=n<=1e5
思路:
用dfs搜索点对,点对中两个点只需要一条边,其余每个点需要一条边相连。需要读入挂加速。
//
// main.cpp
// 1008
//
// Created by zc on 2017/8/25.
// Copyright © 2017年 zc. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=220000;
const int M=440000;
int d[N],sum;
namespace fastIO {
#define BUF_SIZE 1000000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror)
return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO;
struct node
{
int next,v;
}e[M];
int head[N],cnt;
void init()
{
memset(head,-1,sizeof(head));
cnt=0;
}
void add(int u,int v)
{
e[cnt].v=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
int dfs(int u,int fa)
{
int flag=0;
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
if(!dfs(v,u)) flag=1;
}
sum+=flag;
return flag;
}
int main(int argc, const char * argv[]) {
int T,n,k;
read(T);
while(T--)
{
init();
read(n);read(k);
memset(d,0,sizeof(d));
for(int i=2;i<=n;i++)
{
int t;
read(t);
add(t,i);
add(i,t);
}
sum=0;
dfs(1,-1);
int ans;
if(k<=sum*2) ans=(k+1)/2;
else ans=k-sum;
printf("%d\n",ans);
}
}