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 ...
随机推荐
- [在读] javascript权威指南第六版
耽搁了有大半年没看,记得当时看到5分之2了吧.权威指南是不管读几遍都能觉得有新收获的书^^
- 142. O(1)时间检测2的幂次
用 O(1) 时间检测整数 n 是否是 2 的幂次. 您在真实的面试中是否遇到过这个题? Yes 样例 n=4,返回 true; n=5,返回 false. class Solution { publ ...
- IIS+PHP访问量大时内存爆满等性能问题解决方案
如今还是有许多人在用老掉牙的 IIS6 + PHP.本文解决方法适用于使用 FastCGI 运行 PHP 的用户. 问题原因: 你可以试一试,你在 VPS 上用 IIS6 安装 FastCGI 跑 P ...
- APPCLOUD 判断网络
if(api.connectionType == 'none'){ api.toast({ msg : '当前网络不可用,请检查网络设置', duration : , location : 'midd ...
- Ubuntu系统下安装字体和切换默认字体的方法
参考链接:http://my.oschina.net/itblog/blog/278566 打开Ubuntu的软件中心,搜索:tweak,安装[Unity Tweak Tool]这款软件,如图(由于我 ...
- C#调用C库的注意事项
作者:朱金灿 来源:http://blog.csdn.net/clever101 注意事项一: 从C#的exe进入C库的源码进行调试,需要先"启用非托管代码调试",如下图: 注意事 ...
- SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行。
Oracle数据导入报错:SP2-0734: 未知的命令开头 "imp scott/..." - 忽略了剩余的行. 原因:进入sqlplus里是不能执行imp的(sqlplus不认 ...
- IOS实现弹出菜单效果MenuViewController(背景 景深 弹出菜单)
在写项目时,要实现一个从下移上来的一个弹出菜单,并且背景变深的这么一个效果,在此分享给大家. 主要说一下思路及一些核心代码贴出来,要想下载源码, 请到:http://download.csdn.net ...
- Azure 8 月新公布
Azure 8 月新发布:Cosmos DB 每分钟请求单位,存储的托管磁盘及促销,高级和标准磁盘存储大尺寸磁盘,高级磁盘存储小尺寸磁盘. Azure Cosmos DB:每分钟请求单位为您降低成本, ...
- 使用 Cosmos DB 创建和查询 NoSQL 表
本教程演示如何使用 Azure 门户创建 Azure Cosmos DB 帐户,然后使用 DocumentDB .NET API 创建具有分区键的文档数据库和集合.通过在创建集合时定义分区键,应用程序 ...