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
Source
Recommend
liuyiding | We have carefully selected several similar problems for you: 6181 6180 6179 6178 6177
题意:给出一棵树,有n个节点,树上要安排k只猴子,要求每只猴子至少要与一直其他的猴子相邻问树上最少留多少条边能按照要求安排好这些猴子
思路:其实我们只需要找这颗树上最多有多少条不相交的边就可以了,因为我们贪心的策略肯定是最好是一条边对应两只猴子,所以我们只要找到最多的边数ans,如果ans*2<k的话,剩下的猴子就只能是一直猴子对应一条边喽
找最多的边我们就从树根开始找,如果一个父亲节点vis=0,并且他的子节点经过深搜从叶子节点回溯回来的vis还是0那么这就是一条边
ac代码:
#include <bits/stdc++.h>
namespace fastIO{
#define BUF_SIZE 100000000
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;
using namespace std;
const int maxn=100000+10;
int T;
int N,K;
int ans=0;
struct Edge{
int to;
int next;
}edge[2*maxn];
int cntE=0;
int head[maxn];
bool vis[maxn];
void addedge(int u,int v){
edge[cntE].to=v;
edge[cntE].next=head[u];
head[u]=cntE++;
edge[cntE].to=u;
edge[cntE].next=head[v];
head[v]=cntE++;
}
bool dfs(int x){
bool flag=false;
for (int i=head[x];i!=-1;i=edge[i].next){
int v=edge[i].to;
if (vis[v]) continue;
vis[v]=true;
if (dfs(v))
flag=true;
}
if (flag){
ans++;
return false;
}
else
return true;
}
int main(){
read(T);
while (T--){
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
cntE=0;
read(N);
read(K);
for (int i=1;i<=N-1;i++){
int x;
read(x);
addedge(x,i+1);
}
ans=0;
vis[1]=1;
dfs(1);
if (2*ans<=K){
printf("%d\n",ans+K-2*ans);
}
else
printf("%d\n",(K-1)/2+1);
}
}