树的直径

树的直径有两种求法

1.两遍 dfs 法, 便于输出具体方案,但是无法处理负权边

2.DP 法,代码量少,可以处理负权边

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAXN = 200005;
int n, k, head[MAXN], nume, fa[MAXN], ans, ma, t, d[MAXN], s;
bool f[MAXN];
struct edge {
int to, nxt, dis;
}e[MAXN<<1];
void adde(int from, int to) {
e[++nume].to = to;
e[nume].dis = 1;
e[nume].nxt = head[from];
head[from] = nume;
}
void dfs1(int u, int dep) {
if(f[u]) return ;
f[u] = 1;
if(dep > ma && u != 1) {
ma = dep;
k = u;
}
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
dfs1(v, dep + e[i].dis);
}
}
void del(int u) {
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(v == fa[u]) {
e[i].dis = e[((i - 1) ^ 1) + 1].dis = -1;
del(v);
}
}
}
void dfs2(int u, int dep) {
f[u] = 1;
if(dep > ma && u != t) {
ma = dep; k = u;
} for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(!f[v]) {
fa[v] = u;
dfs2(v, dep + e[i].dis);
}
}
}
void dp(int u) {
f[u] = 1;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(!f[v]) {
dp(v);
ma = max(ma, d[u] + d[v] + e[i].dis);
d[u] = max(d[u], d[v] + e[i].dis);
}
}
}
int main() {
cin >> n >> s;
for(int i = 1; i < n; i++) {
int u, v;
scanf("%d %d", &u, &v);
adde(u, v);
adde(v, u);
}
dfs1(1, 0);
ma = 0;t = k; k = 0;
memset(f, 0, sizeof(f));
dfs2(t, 0);
ans += 2 * (n - 1) ;
ans -= ma - 1;
if(s == 2) {
del(k);
memset(f, 0, sizeof(f));
ma = 0;
dp(1);
ans -= ma - 1;
}
cout << ans << endl;
return 0;
}

洛谷 [P3629] 巡逻的更多相关文章

  1. BZOJ1912 APIO2010 洛谷P3629 巡逻

    Description: 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任 ...

  2. [洛谷P3629] [APIO2010]巡逻

    洛谷题目链接:[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以 ...

  3. 洛谷 P3629 [APIO2010]巡逻 解题报告

    P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...

  4. 洛谷 P3629 [APIO2010]巡逻

    题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...

  5. 【洛谷 P3629】 [APIO2010]巡逻 (树的直径)

    题目链接 容易发现,当加一条边时,树上会形成一个环,这个环上的每个点都是只要走一次的,也就是说我们的答案减少了这个环上点的个数,要使答案最小,即要使环上的点最多,求出直径\(L\),则答案为\(2(n ...

  6. 洛谷P3629 [APIO2010]巡逻(树的直径)

    如果考虑不算上新修的道路,那么答案显然为\(2*(n-1)\). 考虑\(k=1\)的情况,会发现如果我们新修建一个道路,那么就会有一段路程少走一遍.这时选择连接树的直径的两个端点显然是最优的. 难就 ...

  7. BZOJ1912或洛谷3629 [APIO2010]巡逻

    一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...

  8. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  9. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

随机推荐

  1. Mysql 8.0 新特性

    转载:https://www.jianshu.com/p/be29467c2b0c

  2. Java String Integer转换 练习:编程求字符串“100”和“150”按十进制数值做差后的结果以字符串形式输出。

    package com.swift; public class String_To_Integer_Test { public static void main(String[] args) { /* ...

  3. comboBox 下拉宽度自适应

    ///适用combobox绑定datatable private void comboBox_DataSourceChanged(object sender, EventArgs e) { Combo ...

  4. vue 点击下拉框

    data: { hide:false, zhi:"全部" }, <div class="item"> <div class="c2c ...

  5. 转 救命的教程 anaconda下载安装包网络错误的解决办法

    折腾了一天,终于找到了这个解决办法 https://blog.csdn.net/sinat_29315697/article/details/80516498

  6. 【贪心 计数】bzoj2006: [NOI2010]超级钢琴

    这么经典的贪心我怎么现在才做啊…… Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐. 这架超级钢琴可以弹奏出n个 ...

  7. MySQL查询显示连续的结果

    #mysql中 对于查询结果只显示n条连续行的问题# 在领扣上碰到的一个题目:求满足条件的连续3行结果的显示 X city built a new stadium, each day many peo ...

  8. 使用slot-scope复制vue中slot内容

    有时候我们的vue组件需要复制使用者传递的内容. 比如我们工程里面的轮播组件需要使用复制的slot来达到循环滚动的效果 使用者关注轮播内容的静态效果,组件负责让其滚动起来 组件: <div cl ...

  9. 【nginx】 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

    2013/10/22 20:05:49 [error] 12691#0: *6 FastCGI sent in stderr: "Primary script unknown" w ...

  10. Linux下的jdk安装

    我使用的是CentOS7,jdk使用的是JDK1.8 下载好以后,将jdk传到我自己的目录:/home/tool下,通过 tar -xzvf  jdk-8u131-linux-x64.tar.gz解压 ...