HDU 6686 Rikka with Travels 树的直径
题意:定义两点之间的距离为从一个点到另一个点经过的点数之和(包括这两个点),设二元组(x, y)为两条不相交的路径,一条长度为x,一条长度为y,问二元组(x, y)出现了多少次?
思路:直接上jls的讲解:
基础直径练习题。
考虑判断 能不能出现。劼论:任意取树上的一条直径,那么如果 能出现,那么一定存在一 种方案使得直径的两端都被使用了。证明很简单:假设存在一个端点没有被使用,那么考虑两条直线的 四个端点 ,一定可以把一个端点给移动到直径的这个端点上,因为直径是树上长的路径,因 此这次移动一定不会减少路径的长度。
考虑对每一个长度 ,求可以满足的长的 ,这样所有小于等于 的值也都能被满足。考虑在直径上 计算这些值:第一种情况,直径的两端分属不同的路径,那么可以枚举直径的一个端点那条路径在直径 上的后一个点,那么这一条路径的大长度就是这个点到直径端点的距离加上这个点往直径外的大 延伸长度,另一条路径的大长度也可以类似地求,其中大延伸长度可以用一个 的 DFS 计算出 来。第二种情况是有一条路径就是这条直径,那么另一条路径就是这条直径之外的长路径长度,这个 只要把直径上的点都删了再求一遍直径就行。
总的时间复杂度为 O(n)。
代码:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 100010;
vector<int> G[maxn];
int mp[maxn], mx_dis[maxn], f[maxn],Mx[maxn];
bool v[maxn], v1[maxn];
int root, mx, now;
vector<int> a;
void add(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
void dfs(int x, int fa, int dis, bool flag) {
f[x] = fa;
v1[x] = flag;
if(dis > mx) {
mx = dis;
now = x;
}
for (auto y : G[x]) {
if(y == fa || v[y]) continue;
dfs(y, x, dis + 1, flag);
}
}
int dfs1(int x, int fa) {
int mx = 0;
for (auto y : G[x]) {
if(v[y] || y == fa) continue;
mx = max(mx, dfs1(y, x));
}
return mx + 1;
}
int main() {
int T, x, y, n;
// freopen("6686in.txt", "r", stdin);
// freopen("out1.txt", "w", stdout);
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
a.clear();
for (int i = 1; i <= n; i++)
G[i].clear();
for (int i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
}
for (int i = 1; i <= n; i++)
v[i] = v1[i] = mp[i] = f[i] = mx_dis[i] = 0;
root = 1, mx = 0;
dfs(root, 0, 1, 0);
root = now, mx = 0;
dfs(root, 0, 1, 0);
for (int i = now; i; i = f[i]) {
v[i] = 1;
a.push_back(i);
}
for (auto x : a) {
mx_dis[x] = dfs1(x, 0);
}
for (int i = 1; i <= n; i++) v1[i] = 0;
int tmp = 0;
for (int i = 1; i <= n; i++) {
if(v[i] == 0 && v1[i] == 0) {
now = mx = 0;
dfs(i, 0, 1, 0);
dfs(now, 0, 1, 1);
tmp = max(tmp, mx);
}
}
mp[a.size()] = tmp;
mp[tmp] = a.size();
Mx[a.size()] = 0;
for (int i = a.size() - 2; i >= 0; i--) {
Mx[i + 1] = max(Mx[i + 2], (int)a.size() - i - 2 + mx_dis[a[i + 1]]);
}
for (int i = 0; i < a.size() - 1; i++) {
int x = i + mx_dis[a[i]];
int y = Mx[i + 1];
mp[x] = max(mp[x], y);
mp[y] = max(mp[y], x);
}
LL ans = 0;
mx = 0;
for (int i = a.size(); i >= 1; i--) {
mx = max(mx, mp[i]);
ans += mx;
}
printf("%lld\n", ans);
}
}
HDU 6686 Rikka with Travels 树的直径的更多相关文章
- hdu 4607 Park Visit 求树的直径
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n) ...
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- Hdu 4612 Warm up (双连通分支+树的直径)
题目链接: Hdu 4612 Warm up 题目描述: 给一个无向连通图,问加上一条边后,桥的数目最少会有几个? 解题思路: 题目描述很清楚,题目也很裸,就是一眼看穿怎么做的,先求出来双连通分量,然 ...
- hdu 4123 Bob’s Race 树的直径+rmq+尺取
Bob’s Race Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Probl ...
- F - Warm up - hdu 4612(缩点+求树的直径)
题意:有一个无向连通图,现在问添加一条边后最少还有几个桥 分析:先把图缩点,然后重构图为一棵树,求出来树的直径即可,不过注意会有重边,构树的时候注意一下 *********************** ...
- HDU 4123 Bob’s Race 树的直径+单调队列
题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...
- F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解
题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...
- hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...
- HDU 4607 Park visit (求树的直径)
解题思路: 通过两次DFS求树的直径,第一次以随意点作为起点,找到距离该点距离最远的点,则能够证明这个点一定在树的直径上,然后以该点为起点进行DFS得到的最长路就是树的直径. 最后的询问,假设K &l ...
随机推荐
- 030:spaceless和autoescape 标签
1.spaceless 标签: spaceless 标签:移除html标签中的空白字符.包括空格.tab键.换行等.示例代码如下: {% spaceless %} <p> <a hr ...
- linux运维、架构之路-数据库迁移
一.wordpress搭建 1.wordpress下载部署 cd /server/tools/ wget https://cn.wordpress.org/wordpress-4.8.1-zh_CN. ...
- CentOS下安装Chrome浏览器
1. 下载安装脚本, 在下载目录中,执行以下命令,将安装脚本下载到本地 wget https://intoli.com/install-google-chrome.sh 2.然后授予可执行权限 chm ...
- 持续优化云原生体验,阿里云在Serverless容器与多云上的探索
近日,阿里云宣布推出Serverless Kubernetes服务此举意在降低容器技术的使用门槛.简化容器平台运维.并同时发布阿里云服务对Open Service Broker API标准支持,通过一 ...
- python_012
一.内置函数 1.sorted()排序函数 a:语法sorted(Iterable,key = None,reverse = False) Iterable:可迭代对象;key:排序规则(函数) ls ...
- 20180823-Java包
Java 包(package) 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包 ...
- 201903-2 CCF 二十四点
题面: 考场写的30分== #include<bits/stdc++.h> using namespace std; stack<int>st; stack<char&g ...
- sqlalchemy.exc.NoForeignKeysError:Can't find any foreign key relationships between
这句话的意思是,两张表之间的外键找不到,首先看看外键设置正确了没,如果外键没问题,看看是不是_tablename_设置了没,就是再model中,定义类的时候,表格名称要_tablename_设置一下, ...
- jenkins自动化打包报错:gradle: 未找到命令
shell脚本如下: cd /home/wangju/gitProject/Automation echo "************************开始清理环境********** ...
- EntityFramework经典数据访问层基类——增删改查
namespace StudentSys.DAL { public class BaseService<T>:IDisposable where T:BaseEntity,new() { ...