题意:
给出一个无向树,每一个节点代表一个城市,问从给出的城市出发,每一次到达一个城市之后都会将距离他为1的城市访问完,第二天继续访问其它没有访问的城市,问最多可以持续多少天。

思路:
简单的树形dp,跟树形dp模板题没有上司的舞会一样,设dp[i][0]代表不把i作为休息点的以i为根的最大天数,dp[i][1]代表把i作为休息点的以i为根的最大天数,那么转移dp[i][0]+=max(dp[儿子][0],dp[儿子][1]),dp[i][1]+=dp[儿子][0],也就是不选择这个点作为休息点那么对于儿子节点没有要求,选择后儿子节点就不能作为休息点了。

代码如下:

#include<bits/stdc++.h>
#define LL long long
#define all(x) (x).begin(),(x).end()
#define le(x) ((int)(x).size())
#define pii pair<int,int>
#define PII pair<LL,LL>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define db printf("Here!\n");
using namespace std;
const double eps=1e-8;
const double Pi=4.0*atan(1.0);
const LL inf=1e9+10;
const int N=5e5+5;
const int M=2e6+5;
const int mod=1e9+7;
int n,m,k,t,T,len,op,x,y,z;
vector<int>v[N];
int dp[N][2];
void dfs(int now,int fa){
    for(auto e:v[now]){
        if(e==fa)continue;
        dfs(e,now);
        dp[now][0]+=max(dp[e][1],dp[e][0]);
        dp[now][1]+=dp[e][0];
    }
    dp[now][1]++;
}
void solve(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        v[x].pb(y);
        v[y].pb(x);
    }
    dfs(k,k);
    printf("%d\n",dp[k][1]);//起点已经固定了
}
int main(){
    //int o;scanf("%d",&o);
    //while(o--){
        solve();
    //}
    return 0;
}