牛客-旅游(树形dp)

题目链接

题目:
在这里插入图片描述
题解:

这题其实是一个最大独立集的问题。先解释啥什么是最大独立集:一个点集,集合里面的点之间没有公共边,即每两个点之间没有边将他们连接起来,且集合中的点的数量最大。

然后再来看这题,可以用dp来解决此问题,设dp[i][1]表示 点i在点集里,dp[i][0]表示 点 i 不在点集里。那么状态转移很容易可以写出来:
dp[u][1]+=dp[v][0];
dp[u][0]+=max(dp[v][1],dp[v][0]);

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=5e5+5;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const double pi=acos(-1);
int head[MAXN];
int cnt=0;
int dp[MAXN][2];
struct node
{
    int to;
    int next;
}e[MAXN<<1];
void add(int u,int v){
    e[cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void dfs(int u,int f){
    dp[u][1]=1;
    dp[u][0]=0;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].to;
        if(v==f) continue;
        dfs(v,u);
        dp[u][1]+=dp[v][0];
        dp[u][0]+=max(dp[v][1],dp[v][0]);
    }
}
int main(){
    memset(head,-1,sizeof head);
    int n,s;
    cin>>n>>s;
    for(int i=1;i<=n-1;i++){
        int u,v;
        cin>>u>>v;
        add(u,v);
        add(v,u);
    }
    dfs(s,-1);
    printf("%d\n",dp[s][1]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值