题目链接:https://www.nowcoder.com/acm/contest/87/G

分析:

1、对于点cur,dp[cur][0]表示在该点住宿;dp[cur][1]表示其某个子结点住宿,自己被访问到;dp[cur][2]表示其父结点住宿,自己被访问到;

2、如果dp[cur][0],则cur的子结点全是2状态

3、如果dp[cur][2],则cur的子结点要么为0状态,要么为1状态,取这两个状态的最大值累加。

4、如果dp[cur][1],则cur的子结点至少有一个为0状态,其余的为1状态,同样是取两个状态的最大值累加;

不过,若每个子结点都是取1状态时为最优,则必须在他们当中找出一个损失最小的0状态,所以记录每个结点1状态与0状态差值的最小值,然后将变为0状态后损失最小的结点变为0状态即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<fstream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define lowbit(x) (x & (-x))
const double eps = 1e-8;
inline int dcmp(double a, double b){
if(fabs(a - b) < eps) return 0;
return a > b ? 1 : -1;
}
typedef long long LL;
typedef unsigned long long ULL;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
const double pi = acos(-1.0);
const int MAXN = 500000 + 10;
const int MAXT = 10000 + 10;
using namespace std;
int dp[MAXN][3];
vector<int> v[MAXN];
int dfs(int cur, int id, int fa){
if(dp[cur][id] != -INT_INF) return dp[cur][id];
int len = v[cur].size();
if(id == 0){
dp[cur][id] = 1;
for(int i = 0; i < len; ++i){
if(v[cur][i] == fa) continue;
dp[cur][id] += dfs(v[cur][i], 2, cur);
}
}
else if(id == 1 && v[cur].size() > 0){
dp[cur][id] = 0;
int dif = INT_INF;
bool ok = false;
for(int i = 0; i < len; ++i){
if(v[cur][i] == fa) continue;
if(dfs(v[cur][i], 0, cur) >= dfs(v[cur][i], 1, cur)){
ok = true;
dp[cur][id] += dfs(v[cur][i], 0, cur);
}
else{
dp[cur][id] += dfs(v[cur][i], 1, cur);
dif = min(dif, dfs(v[cur][i], 1, cur) - dfs(v[cur][i], 0, cur));
}
}
if(!ok){
dp[cur][id] -= dif;
}
}
else if(id == 2){
dp[cur][id] = 0;
for(int i = 0; i < len; ++i){
if(v[cur][i] == fa) continue;
dp[cur][id] += max(dfs(v[cur][i], 0, cur), dfs(v[cur][i], 1, cur));
}
}
return dp[cur][id];
}
int main(){
int n, s;
scanf("%d%d", &n, &s);
for(int i = 1; i <= n; ++i){
dp[i][0] = dp[i][1] = dp[i][2] = -INT_INF;
}
int x, y;
for(int i = 0; i < n - 1; ++i){
scanf("%d%d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
printf("%d\n", dfs(s, 0, -1));
return 0;
}

  

牛客小白月赛3---G 旅游(树形dp)的更多相关文章

  1. 牛客小白月赛2 G 文 【模拟】

    链接:https://www.nowcoder.com/acm/contest/86/G来源:牛客网 题目描述 Sεlιнα(Selina) 开始了新一轮的男友海选.她要求她的男友要德智体美劳样样都全 ...

  2. 牛客小白月赛6 G 指纹锁 set的自动排序 模板

    链接:https://www.nowcoder.com/acm/contest/136/G来源:牛客网 题目描述     HA实验有一套非常严密的安全保障体系,在HA实验基地的大门,有一个指纹锁.   ...

  3. 牛客小白月赛1 G あなたの蛙は旅⽴っています【图存储】【DP】

    题目链接:https://www.nowcoder.com/acm/contest/85/G 思路: DP 空间可以优化成一维的, 用一维数组的 0 号单元保存左斜对角的值即可. 存图这里真不好理解 ...

  4. 牛客小白月赛1 G あなたの蛙は旅⽴っています【DP】

    题目链接 https://www.nowcoder.com/acm/contest/85/G 思路 按照题解上的方式 存取数据 然后DP一下 就可以了 AC代码 #include <cstdio ...

  5. 牛客小白月赛5 G 异或(xor) 【找规律】

    题目链接: https://www.nowcoder.com/acm/contest/135/g 题目描述 从前,Apojacsleam家的水族箱里,养了一群热带鱼. 在这几条热带鱼里,Apojacs ...

  6. 牛客网 牛客小白月赛2 G.文

    G.文 链接:https://www.nowcoder.com/acm/contest/86/G 这个题wa了一发,有点智障,浮点数,式子里面要*1.0,忘了,然后wa了,改了就过了(脑子有坑) 代码 ...

  7. 牛客小白月赛14 -G (筛法)

    题目链接:https://ac.nowcoder.com/acm/contest/879/G 题意:给定A1和A数组公式: 以及B数组: 求 思路:利用筛法更新b数组,最后求异或和即可. AC代码: ...

  8. 牛客小白月赛13 G(双向搜索)

    AC通道 两边同步搜,一步里面A走一次B走两次,遇到对方走过的地方就得到了答案. #include <bits/stdc++.h> using namespace std; const i ...

  9. 牛客小白月赛18 G Forsaken的三维数点

    思路: 这是一道树状数组和二分的题,用线段树空间直接爆,时间也会超 然后这道题我犯了一个很低级的错误,导致我wa了十发左右,一个int型变量用lld输入,然后他给的提示是运行错误,我哭了,我一直以为是 ...

  10. 牛客小白月赛17 G 区间求和

    传送门 题意: 题解: 原本想着使用暴力方法: 1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream& ...

随机推荐

  1. Chrome的一个问题

    报错:Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extensi ...

  2. MySQL忘记密码如何重置

    一]进入服务器下,我用的是centos版本 vim /etc/my.cnf 1 vim[二]找到mysqld的部分然后在下面添加上一句代码,意思是跳过密码直接进入,然后保存退出 skip-grant- ...

  3. windows下安装elasticsearch-6.4.3和elasticsearch-head插件

    windows下安装elasticsearch-6.4.3和elasticsearch-head插件 博客分类: elasticsearch es  ElasticSearch下载地址:https:/ ...

  4. LockSupport源码分析

    LockSupport提供park()和unpark()方法实现线程阻塞和唤醒.底层实现是通过sun.misc.Unsafe的park和unpark. 关于sun.misc.Unsafe的说明请参见我 ...

  5. PAT T1019 Separate the Animals

    暴力搜索加剪枝,二进制保存状态,set去重~ #include<bits/stdc++.h> using namespace std; ; string s[maxn]; struct n ...

  6. SQL的四种连接(内连接,外连接)

    一,内连接(inner join) 内连接(INNER JOIN):分显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行.(所谓的连接表就是数据库在做查询形成的中间表). 1.隐式的内连接 没 ...

  7. java是什么

    Java是一个纯的面向对象的程序设计语言 java是一种强类型语言,特点是: 1,跨平台 2,面向对象 3,简单易用 跨平台指的是只要有java虚拟机的平台,都可以运行java代码. Java继承了C ...

  8. Spark入门:第1节 Spark概述:1 - 4

    2.spark概述 2.1 什么是spark Apache Spark™ is a unified analytics engine for large-scale data processing. ...

  9. 敏捷团队协作:Confluence简易教程

      0.Confluence简介 Confluence是一个企业级的Wiki软件,可用于在企业.部门.团队内部进行信息共享和协同编辑. 1.基础概念 Confluence的使用并不复杂,只需掌握如下几 ...

  10. How to recover if NMC cound not connect

    Some times we suddently find that the NMC can not login,. You would see the sybase database error if ...