VIJOS1476 旅行规划(树形Dp + DFS暴力乱搞)
题意:
给出一个树,树上每一条边的边权为 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暴力乱搞)的更多相关文章
- VIJOS1476旅游规划[树形DP 树的直径]
描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包 ...
- 树形DP+贪心(乱搞)(HDU4714)
题意:给出一个树形图,要求把该树形成一个环最少的步骤(断开一条边和形成一条边都需一步) 分析:很明显,要想把树形成一个环,就要先把其分裂成m条子链之后把子链形成环需要的步骤是2*m+1,所以只需要m最 ...
- HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca
Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...
- P1642 规划 01分数规划+树形DP
$ \color{#0066ff}{ 题目描述 }$ 某地方有N个工厂,有N-1条路连接它们,且它们两两都可达.每个工厂都有一个产量值和一个污染值.现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工 ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...
- poj 3140 Contestants Division(树形dp? dfs计数+枚举)
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- 树的直径的求法即相关证明【树形DP || DFS】
学习大佬:树的直径求法及证明 树的直径 定义: 一棵树的直径就是这棵树上存在的最长路径. 给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间的距 ...
- 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)
题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...
随机推荐
- shell脚本由基础变量及特殊变量($@、$*、$#等)到实战。
一.shell脚本建立: shell脚本通常是在编辑器(如vi/vim)中编写,也可以在命令行中直接执行: 1.脚本开头: 规范的脚本第一行需要指出有哪个程序(解释器)来执行脚本中的内容,在L ...
- phpdesigner 配置SVN
- P1816 忠诚 倍增
链接:https://www.luogu.org/problem/show?pid=1816 题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k ...
- SpringBoot 2.x (9):整合Mybatis注解实战
SSM框架再熟悉不过了,不过以前通常是使用XML写SQL语句 这里用SpringBoot整合Mybatis并且使用注解进行开发 依赖: <!-- Mybatis --> <depen ...
- jQuery3.2.1 和2.0和 1区别
1. 移除旧的IE工作区新的最终版最主要的目标是更加快速,更加时尚,因此,那些支持早于IE9版本的相关技术与工作区都被移除了.这意味着如果你想要或者需要支持IE6-8,你必须用回1.12版本,因为甚至 ...
- mybatis实现使用原生的sql
1.相应的xml文件中 <select id="selectByCategories" resultType="map" parameterType=&q ...
- ExpandableListView 安卓二级菜单
ExpandableListView可以显示一个视图垂直滚动显示两级列表中的条目,这不同于列表视图(ListView).ExpandableListView允许有两个层次:一级列表中有二级列表.比如在 ...
- 异步 Thread
Threads 最早的版本,微软推荐不要再使用Thread了thread不支持带返回值的方法本身也没有线程回调,但是可以自己做一个 private void btnThreads_Click(obje ...
- leetcode_1095. Find in Mountain Array_[Binary Search]
https://leetcode.com/problems/find-in-mountain-array/ 题意:给定一个MountainArray(定义见题目),找到其中最早出现的target值的下 ...
- history 路由且带二级目录的Apache配置
有多个项目目录的时候 由于项目不知一个,所以不得不为每一个项目建一个专有的文件夹,这就导致了在配置nginx的时候会出现二级目录 - step1: 修改 vue.config.js 添加配置 ...