【BZOJ4813】小Q的棋盘(CQOI2017)-贪心+DFS

测试地址:小Q的棋盘
做法:这一题是之前做的,现在整理一下放在这里。
这一题应该使用DFS来完成。
注意到一个显然的结论:最优解中一条边一定不会被走过两次以上,而且走过一次的边一定会连成一条链。那么我们应该找到一条尽量长的从点0出发的链,在这条链上走一次能走到一个新点,这一点用DFS就可以求出。如果还剩下步数,那么就在路径中间伸出的枝杈上走两次来得到一个新点(有去有回),直到没有新点或者剩余步数不足为止,可以证明按这个方法找到的方案一定是最优的。复杂度O(V)
以下是本人代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int v,n,first[110]={0},tot=0,ans,maxdep=0;
struct edge {int v,next;} e[210];

void insert(int a,int b)
{
  e[++tot].v=b,e[tot].next=first[a],first[a]=tot;
}

void dfs(int v,int dep,int f)
{
  maxdep=max(dep,maxdep);
  for(int i=first[v];i;i=e[i].next)
    if (e[i].v!=f) dfs(e[i].v,dep+1,v);
}

int main()
{
  scanf("%d%d",&v,&n);
  for(int i=1,a,b;i<v;i++)
  {
    scanf("%d%d",&a,&b);
    insert(a,b),insert(b,a);
  }

  dfs(0,0,-1);

  if (maxdep>n) printf("%d",n+1);
  else printf("%d",min(maxdep+(n-maxdep)/2+1,v));

  return 0;
}
posted @ 2017-05-19 14:02  Maxwei_wzj  阅读(103)  评论(0编辑  收藏  举报