题意:
给出一个无向树,每一个节点代表一个城市,问从给出的城市出发,每一次到达一个城市之后都会将距离他为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; }