HDU - 6178:Monkeys (贪心&树上最大匹配输&输入优化)
Posted hua-dong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 6178:Monkeys (贪心&树上最大匹配输&输入优化)相关的知识,希望对你有一定的参考价值。
Print the minimum possible number of remaining edges.
InputThe 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 a 1 ,a 2 ,…,a N−1 a1,a2,…,aN−1
, it means that there is an edge between vertex a i ai
and vertex i+1 (1 <= a i ai
<= i).
OutputFor 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
题意:给定一棵树,有K个猴子,现在让你把猴子放到节点上(一个节点最多一个猴子),求最少留多少边,使得每个连通块的猴子数不为1 。
思路:尽量把两个猴子用一条边连接起来。所以我们先贪心,有多少个“边匹配”,假设最大值为cnt。然后如果够,那么答案是(K+1)/2;如果不够,则加边即可,答案是cnt+(K-cnt*2)。
求最大“边匹配”的方法是贪心,从下想上贪,因为一个点最大贡献到一条边,所以把u和没有被匹配的fa[u]匹配,其效果不会比fa[u]和fa[fa[u]]匹配差。
不用输入优化会T。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define ll long long using namespace std; const int maxn=1000010; int vis[maxn],fa[maxn],cnt,ans; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void read(int &sum){ char ch=nc(); sum=0; while(!(ch>=‘0‘&&ch<=‘9‘))ch=nc(); while(ch>=‘0‘&&ch<=‘9‘) sum=sum*10+ch-48,ch=nc(); } int main() { int T,N,K; read(T); while(T--){ read(N);read(K); ans=cnt=0; rep(i,1,N) vis[i]=0; rep(i,2,N) read(fa[i]); for(int i=N;i>=2;i--) if(!vis[i]&&!vis[fa[i]]) ans++,vis[fa[i]]=1; if(ans*2>=K) printf("%d ",(K+1)/2); else printf("%d ",ans+(K-ans*2)); } return 0; }
以上是关于HDU - 6178:Monkeys (贪心&树上最大匹配输&输入优化)的主要内容,如果未能解决你的问题,请参考以下文章