HDU6178 Monkeys

来源:互联网 发布:还原数据库找不到文件 编辑:程序博客网 时间:2024/06/18 16:39

题目

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.
 

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,,aN1, 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
24 41 2 34 31 1 1


Sample Output
22
 
题目大意

  先不写

解题思路

  自己蠢的一比,赛后看数据,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;}




原创粉丝点击