【CQOI2017】【BZOJ4813】Little Q's chessboard DFS

Topic description

  There is a tree, you want to start walking from the point \(0\) , you can take \(m\) steps and ask you how many different points you can pass at most.

  \ (n \ leq 100 \)

answer

  The author's approach is DP (a simple tree-shaped DP), but it can be made directly through a DFS.

  First DFS the entire tree, let \(d\) be the maximum depth of all points.

  If \(m<d\) , then obviously walking the longest chain is optimal, and the answer is \(m+1\)

  Otherwise, we can go to the end along this chain first, and we can go to other subtrees in the process. Every two steps, we can go to a new point. The answer is \(\min(n,d+\lfloor\frac {m-d+1}{2}\rfloor)\)

  Time complexity: \(O(n)\)

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
    if(a>b)
        swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
    char str[100];
    sprintf(str,"%s.in",s);
    freopen(str,"r",stdin);
    sprintf(str,"%s.out",s);
    freopen(str,"w",stdout);
#endif
}
int rd()
{
    int s=0,c;
    while((c=getchar())<'0'||c>'9');
    do
    {
        s=s*10+c-'0';
    }
    while((c=getchar())>='0'&&c<='9');
    return s;
}
void put(int x)
{
    if(!x)
    {
        putchar('0');
        return;
    }
    static int c[20];
    int t=0;
    while(x)
    {
        c[++t]=x%10;
        x/=10;
    }
    while(t)
        putchar(c[t--]+'0');
}
int upmin(int &a,int b)
{
    if(b<a)
    {
        a=b;
        return 1;
    }
    return 0;
}
int upmax(int &a,int b)
{
    if(b>a)
    {
        a=b;
        return 1;
    }
    return 0;
}
int maxd;
vector<int> g[110];
void dfs(int x,int fa,int dep)
{
    maxd=max(maxd,dep);
    for(auto v:g[x])
        if(v!=fa)
            dfs(v,x,dep+1);
}
int main()
{
    open("chessbord");
    int n,m;
    scanf("%d%d",&n,&m);
    int x,y;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        x++;
        y++;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dfs(1,0,1);
    int ans;
    if(m<maxd)
        ans=m+1;
    else
        ans=min(n,maxd+(m-maxd+1)/2);
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324706786&siteId=291194637