hdu 6178

来源:互联网 发布:淘宝运营月计划书 编辑:程序博客网 时间:2024/06/14 22:26

题解:这是树上的最大二分匹配,因为这颗树是连通的所以,可以直接从叶子节点开始向上贪心,每两个配一对即可

记得用读入优化即可。

之前写的HK算法现在过不了

[cpp] view plain copy
print?
  1. #include<iostream>  
  2. #include<cstring>  
  3. #include<algorithm>  
  4. #include<cstdio>  
  5. #include<vector>  
  6. #include<queue>  
  7. using namespace std;  
  8. inline char nc(){  
  9.     static char buf[100000],*p1=buf,*p2=buf;  
  10.     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;  
  11. }  
  12. inline int _read(){  
  13.     char ch=nc();int sum=0;  
  14.     while(!(ch>='0'&&ch<='9'))ch=nc();  
  15.     while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();  
  16.     return sum;  
  17. }  
  18. const int mx = 100005;  
  19. const int inf = 0x3f3f3f3f;  
  20. int n,k;  
  21. int p[mx];  
  22. int vis[mx];  
  23. int solve(){  
  24.     int ans = 0;  
  25.     for(int i = n; i>=2; i--)  
  26.         if(!vis[p[i]]&&!vis[i]){  
  27.             ans++;  
  28.             vis[i] = 1;  
  29.             vis[p[i]] = 1;  
  30.         }  
  31.     if(2*ans>=k)  
  32.         return (k+1)/2;  
  33.     return k-ans;  
  34. }  
  35. int main(){  
  36.     int t;  
  37.     t = _read();  
  38.     while(t--){  
  39.         n = _read();  
  40.         k = _read();  
  41.         memset(vis,0,sizeof(vis));  
  42.         //memset(son,0,sizeof(son));  
  43.         for(int i = 2; i <= n; i++){  
  44.             int u;  
  45.             u = _read();  
  46.             p[i] = u;  
  47.         }  
  48.         printf("%d\n",solve());  
  49.     }  
  50.     return 0;  
  51. }