BZOJ4813: [Cqoi2017]小Q的棋盘

【传送门:BZOJ4813


简要题意:

  给出一棵树,从根节点出发,走n步,求最多能经过多少个点(重复经过不算)


题解:

  贪心

  本来想着树形DP,太麻烦了,懒得码

  首先我们把最长链留到最后走,这样子我们就可以一次性将最长链走完了,那么最长链的每条边的代价就是1

  而其它边的代价就为2(因为要往回走),然后贪心就好了

  特殊情况:

  1.最长链的长度>=步数,直接输出步数

  2.步数足够将整张图走完,直接输出n

  直接在贪心的时候顺便处理就好了


参考代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
struct node
{
    int x,y,next;
}a[210];int len,last[110];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int dep[110];
void dfs(int x,int fa)
{
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(y!=fa)
        {
            dfs(y,x);
            dep[x]=max(dep[y]+1,dep[x]);
        }
    }
}
int main()
{
    int v,n;
    scanf("%d%d",&v,&n);
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<v;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        x++;y++;
        ins(x,y);ins(y,x);
    }
    memset(dep,0,sizeof(dep));
    dfs(1,1);
    int ans=min(dep[1],n)+1;
    n-=ans-1;
    while(ans<v&&n>=2){ans++;n-=2;}
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-03-26 10:05  Star_Feel  阅读(208)  评论(0编辑  收藏  举报