题意:

给出一个树,树上每一条边的边权为 1,求树上所有最长链的点集并。

细节:

可能存在多条最长链!最长链!最长链!重要的事情说三遍

分析:

方法round 1:暴力乱搞Q A Q,边权为正-> d f s 解决,如何标记点集呢,只需要求出最大长度,然后在进行一次遍历,当当前长度等于最长链长的时候就返回 true,并且对沿路的节点进行标记。

好吧这样你就成功的死亡了,还是细节最长链有多条!有多条!有多条!好吧我们再来看一张神奇的图片

点我的最帅最美

想象一下多条最长链一定是根所示的有一条链和一些在同方向的等长的分支组成,所以只 D F S 一次必然在同方向的分支必然不会被标记,所以只要 D F S 两次就好了。

方法round 2:树形 Dp 个人感觉比较反人类,在记录次长和最长的链之外我们只需要在记录一个 f[u][2] 表示距离 u 最远的节点,最后只要统计某个点的最长链是否等于最长链即可。

最后献上一波转移:

if (f[v][0]+1!=f[u][0] || (f[v][0]+1==f[u][0] && cnt>1)) f[v][2]=max(f[u][2], f[u][0])+1;

else f[v][2]=max(f[u][2], fu)+1;


cnt 是某节点儿子节点数

代码:

Round1:

#include<bits/stdc++.h>
#define MAXN 200010
using namespace std; vector<int> Right[MAXN];
int n, dist[MAXN];
bool flag[MAXN]; void dfs(int u, int fa){
for (int i=0; i<Right[u].size(); i++){
int v=Right[u][i];
if (v==fa) continue;
dist[v]=dist[u]+1;
dfs(v, u);
}
} bool solve(int u, int fa, int now, int Max){
for (int i=0; i<Right[u].size(); i++){
int v=Right[u][i];
if (v==fa) continue;
flag[u]|=solve(v, u, now+1, Max);
}
if (now==Max) {
flag[u]=1;
return flag[u];
}
else return flag[u];
} int main(){
scanf("%d", &n);
for (int i=1, x, y; i<n; i++){
scanf("%d%d", &x, &y);
Right[x].push_back(y);
Right[y].push_back(x);
}
memset(dist, 0, sizeof dist);
dfs(0, -1);
int Max=0, maxnum;
for (int i=0; i<n; i++)
if (dist[i]>Max) Max=dist[i], maxnum=i;
memset(dist, 0, sizeof dist);
dfs(maxnum, -1);
Max=0;
int Maxnum;
for (int i=0; i<n; i++)
if (dist[i]>Max) Max=dist[i], Maxnum=i;
solve(maxnum, -1, 0, Max);
solve(Maxnum, -1, 0, Max);
for (int i=0; i<n; i++)
if (flag[i]) printf("%d\n", i);
return 0;
}
Round2:

#include<bits/stdc++.h>
#define MAXN 200010
using namespace std; int f[MAXN][3], n;
vector<int> Right[MAXN]; void Tree_Dp(int u, int fa){
for (int i=0; i<Right[u].size(); i++){
int v=Right[u][i];
if (v==fa) continue;
Tree_Dp(v, u);
if (f[v][0]+1>f[u][0]) f[u][1]=f[u][0], f[u][0]=f[v][0]+1;
else if (f[v][0]+1>f[u][1]) f[u][1]=f[v][0]+1;
}
} void solve(int u, int fa){
int cnt=0;
for (int i=0; i<Right[u].size(); i++){
int v=Right[u][i];
if (v==fa) continue;
if (f[v][0]+1==f[u][0]) cnt++;
}
for (int i=0; i<Right[u].size(); i++){
int v=Right[u][i];
if (v==fa) continue;
if (f[v][0]+1!=f[u][0] || (f[v][0]+1==f[u][0] && cnt>1)) f[v][2]=max(f[u][2], f[u][0])+1;
else f[v][2]=max(f[u][2], f[u][1])+1;
solve(v, u);
}
} int main(){
scanf("%d", &n);
for (int i=1, x, y; i<n; i++){
scanf("%d%d", &x, &y);
Right[x].push_back(y);
Right[y].push_back(x);
}
Tree_Dp(0, -1);
int Max=0;
for (int i=0; i<n; i++) Max=max(Max, f[i][0]+f[i][1]);
solve(0, -1);
for (int i=0; i<n; i++)
if (f[i][0]+max(f[i][1], f[i][2])==Max) printf("%d\n", i);
return 0;
}

VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)的更多相关文章

  1. VIJOS1476旅游规划[树形DP 树的直径]

    描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...

  2. 树形DP+贪心(乱搞)(HDU4714)

    题意:给出一个树形图,要求把该树形成一个环最少的步骤(断开一条边和形成一条边都需一步) 分析:很明显,要想把树形成一个环,就要先把其分裂成m条子链之后把子链形成环需要的步骤是2*m+1,所以只需要m最 ...

  3. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  4. P1642 规划 01分数规划+树形DP

    $ \color{#0066ff}{ 题目描述 }$ 某地方有N个工厂,有N-1条路连接它们,且它们两两都可达.每个工厂都有一个产量值和一个污染值.现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工 ...

  5. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  6. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  7. poj 3140 Contestants Division(树形dp? dfs计数+枚举)

    本文出自   http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...

  8. 树的直径的求法即相关证明【树形DP || DFS】

    学习大佬:树的直径求法及证明 树的直径 定义: 一棵树的直径就是这棵树上存在的最长路径. 给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间的距 ...

  9. 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)

    题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...

随机推荐

  1. 牛客寒假5-I.炫酷镜子

    链接:https://ac.nowcoder.com/acm/contest/331/I 题意: 小希拿到了一个镜子块,镜子块可以视为一个N x M的方格图,里面每个格子仅可能安装`\`或者`/`的镜 ...

  2. 114 Flatten Binary Tree to Linked List 二叉树转换链表

    给定一个二叉树,使用原地算法将它 “压扁” 成链表.示例:给出:         1        / \       2   5      / \   \     3   4   6压扁后变成如下: ...

  3. cmder安装

    官网地址:http://gooseberrycreative.com/cmder/ 一款非常漂亮好用的cmd工具. 在github或者官网下载后解压,点击Cmder.exe即可启动. 32位系统会遇到 ...

  4. 调用submit()方式提交表单

    今天在看高级程序设计时看到的这样一段话: 在以调用submit()方法的形式提交表单时,不会触发submit事件 写了一个小例子做了下测试,的确如此: <form id="fm&quo ...

  5. 关于yii2自带验证码功能不显示问题

    1,验证码不显示: 首先保证你的controler 里面的captcha方法是可访问的,被分配的权限的,这个在rule里面设置. 第二,保证你的PHP GD插件已经被启用, 第三如果这样还是不显示,那 ...

  6. JavaScript之执行环境及作用域

        执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.我们编写的代码是无法访问这个对象的,但解 ...

  7. apache下设置域名多站点访问及禁止apache访问80端口

    apache下设置域名多站点访问 当前系统:macOS High Sierra 域名访问配置指定端口后,不同域名只能配置不同的端口 apache配置目录: sudo vim /etc/apache2/ ...

  8. SQLServer怎样把本地数据导入到远程服务器上(转载)

    平常用到mssql时间比较少,总是过一段时间就忘记应该怎么操作了.当要做mssq把本地数据导入到远程服务器的时候,就去网上搜索很久都没有图解的,所以今天自己收集一下免得下次又到处去找.希望对自己,同时 ...

  9. MYSQL 写入emoji表情字符处理

    这个鬼emoji表情是4个字节,mysql使用的utf8编码,UTF8占3个字节,要存储那个emoji表情需要将mysql编码由UFT8改为UFT8的超集,utf8mb4; 改数据库编码容易引起大面的 ...

  10. HDU 4274 Spy's Work (树形DP,模拟)

    题意: 给定一棵树,每个节点代表一个员工,节点编号小的级别就小,那么点1就是boss了.接下来给出对m个点的限制,有3种符号分别是op=“大于/小于/等于”,表示以第i个点为根的子树所有人的工资之和  ...