题目
Monkeys
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 153428/153428 K (Java/Others)Total Submission(s): 984 Accepted Submission(s): 328
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
题目大意
先不写
解题思路
自己蠢的一比,赛后看数据,100组错了4个,还是最简单那种,竟然还没考虑到,fread都会用了,死在一个小错误上,悲伤逆流成河
看懂了就是一个dfs,找有多少个匹配对,如果找到了一个匹配对,就把这两个节点标记上表示已经用过了,dfs的时候从出入度为2的点进入,
出入度1的点先预处理一下,如果不预处理会出现一个匹配出错
如果从1进来,1和2匹配,这时候到了3,如果3和4匹配那我么很高兴,但是如果3和5匹配那么就出错了,这就是要预处理的原理
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int T,n,k,par[N],sz[N];
int ans[N];
int vis[N];
int num;
bool pa[N];
vector<int> e[N];
inline char nc(){
static char buf[100000+10],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000+10,stdin),p1==p2)?EOF:*p1++;
}
inline int _read(){
char ch=nc();int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
void dfs(int x,int cnt,int fa)
{
if(vis[x])
return ;
vis[x]=1;
cnt++;
if(cnt==2)
{
if(!pa[x]&&!pa[fa])
{
pa[x]=1;
pa[fa]=1;
num++;
cnt=0;
}
else if(pa[x]==0)
{
//vis[x]=0;
cnt=1;
}
// return true;
}
for(auto &v:e[x])
{
if(!vis[v])
{
dfs(v,cnt,x);
//break;
}
}
}
int main()
{
// freopen("1008.in", "r", stdin);
// freopen("data.out", "w", stdout);
T =_read();
while(T--)
{
num=0;
n=_read();
k=_read();
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
memset(pa,0,sizeof(pa));
e[1].clear();
for(int i=2; i<=n; i++)
{
par[i] = _read();
e[i].clear();
e[i].push_back(par[i]);
e[par[i]].push_back(i);
ans[i]++;
ans[par[i]]++;
}
for(int i=1;i<=n;i++)
{
if(ans[i]==1&&!vis[i]&&!vis[e[i][0]])
{
vis[i]=1;
pa[i]=1;
vis[e[i][0]]=1;
pa[e[i][1]];
num++;
}
}
for(int i=1;i<=n;i++)
{
if(ans[i]==2&&!vis[i])
{
dfs(i,0,0);
}
}
int od=k/2;
if(k&1)
{
if(num>=od)
printf("%d\n",od+1);
else
{
printf("%d\n", k-2*num+num);
}
}
else
{
if(num>=od)
printf("%d\n",od);
else
{
printf("%d\n", k-2*num+num);
}
}
}
return 0;
}