旅游题解树形dp
旅游
https://ac.nowcoder.com/acm/problem/15748
首先题意说的很清楚,必须从一开始,然后去找最长的旅游天数,那么我们可以看出是在一颗树上面操作的,那么就是树形dp来解决,我们可以定义dp[i][1/0],什么意思呢,就是第i个地方我是选择住宿还是不住宿(1/0)的最长停留时间,那么我们如果到了以X为根的节点,如果要住那就是dp[x][1]=dp[y][0]+1,父节点住宿了那么儿子节点必然不可以住宿,然后如果没有住宿是不是就是dp[x][0]+=max(dp[y][1],dp[y][0])
#include <bits/stdc++.h> #define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define debug(x) cout << #x << ": " << x << endl; #define debug1(x) cout<<"xxx"<<endl; #define ll long long #define ull unsigned long long #pragma GCC optimize("Ofast","inline","-ffast-math") #pragma GCC target("avx,sse2,sse3,sse4,mmx") #define mse(a,b) memset(a,b,sizeof a); #define fro for #define it int using namespace std; const int maxx=1e6+100; const int mod=1e9+7; //ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } //inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } vector<int>ans[1<<20]; int dp[1<<20][2]; void dfs(int x,int fa) { dp[x][1]=1,dp[x][0]=0; for(auto v:ans[x]) { if(v==fa) continue; dfs(v,x); dp[x][1]+=dp[v][0]; dp[x][0]+=max(dp[v][1],dp[v][0]); // cout<<x<<" "<<dp[x][0]<<" "<<dp[x][1]<<endl; } } int main() { fio; int n,s; cin>>n>>s; for(int i=1,u,v; i<=n-1; i++) { cin>>u>>v; //u=read(),v=read(); ans[u].push_back(v); ans[v].push_back(u); } dfs(s,-1); cout<<dp[s][1]; return 0; }