[关闭]
@ysner 2018-07-18T16:20:49.000000Z 字数 1141 阅读 1605

[CQOI2017]小Q的棋盘

贪心


题面

一棵有个结点的树,问从(根)结点出发,走步最多能经过多少结点。

解析

数据范围亮了
显然,在根结点周围转一圈再回来,走最长链到底是最值的。
于是先求出最长链
如果;
否则剩下步,能多走个点。(画画图发现找不出什么特殊情况


算法复杂度。。。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #define re register
  8. #define il inline
  9. #define ll long long
  10. #define max(a,b) ((a)>(b)?(a):(b))
  11. #define min(a,b) ((a)<(b)?(a):(b))
  12. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  13. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  14. using namespace std;
  15. const int N=1e4+100;
  16. int n,m,h[N],cnt,L;
  17. struct Edge{int to,nxt;}e[N<<1];
  18. il void add(re int u,re int v){e[++cnt]=(Edge){v,h[u]};h[u]=cnt;}
  19. il ll gi()
  20. {
  21. re ll x=0,t=1;
  22. re char ch=getchar();
  23. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  24. if(ch=='-') t=-1,ch=getchar();
  25. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  26. return x*t;
  27. }
  28. il void dfs(re int u,re int fa,re int deep)
  29. {
  30. L=max(deep,L);
  31. for(re int i=h[u];i+1;i=e[i].nxt)
  32. {
  33. re int v=e[i].to;
  34. if(v==fa) continue;
  35. dfs(v,u,deep+1);
  36. }
  37. }
  38. int main()
  39. {
  40. memset(h,-1,sizeof(h));
  41. n=gi();m=gi();
  42. fp(i,1,n-1)
  43. {
  44. re int u=gi()+1,v=gi()+1;
  45. add(u,v);add(v,u);
  46. }
  47. dfs(1,0,1);
  48. if(L>=m) printf("%d\n",m+1);
  49. else printf("%d\n",min(n,L+((m-L+1)>>1)));
  50. return 0;
  51. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注