题目传送门

  传送点I

  传送点II

  传送点III

题目大意

  给定一颗基环树,要求删去其中一条边,使得剩下的图形是一棵树,并且最长路的长度最短,求最长路的最短长度。

  路径可以分为两部分:跨过环 和 在树内部。

  要删除一条边,使图形变为一棵树,那么只能删去环上的一条边,因此,我们无法改变第二部分的路径,但是可以改变第一部分。

  对于第二部分可以通过两次搜索或者树形动态规划解决。

  对于第一部分,考虑枚举删去环上的一条边。但是发现仍然不太方便处理,因为不好维护环上的信息。仍然考虑剖环成链。

  假设环的大小为$k$,从剖点开始依次将所有点标号1到$k$。

  当一条边被删除后,第二部分可能成为答案的情况有两种:

  1. 不跨过剖点和被删边的路径
  2. 跨过剖点但不经过被删边的路径

  因此考虑维护一些数组。

  1. 在$1, 2, \cdots, i$及其所在的树中的最长路。
  2. 从$1$开始,到$1, 2, \cdots, i$及其所在的树中的最长路。
  3. 在$k, k - 1, \cdots, i$及其所在的树中的最长路。
  4. 从$k$开始,到$k, k - 1, \cdots, i$及其所在的树中的最长路。

  这四个部分都可以线性预处理出来。然后枚举删掉的环边就能统计第一部分的答案。

Code

 /**
* Codeforces
* Problem#835F
* Accepted
* Time: 155ms
* Memory: 27100k
*/
#include <bits/stdc++.h>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean; typedef class Edge {
public:
int ed, nx, w; Edge(int ed = , int nx = , int w = ):ed(ed), nx(nx), w(w) { }
}Edge; typedef class MapManager {
public:
int ce;
int* h;
Edge* es; MapManager() { }
MapManager(int n, int m):ce(-) {
h = new int[(n + )];
es = new Edge[(m + )];
memset(h, -, sizeof(int) * (n + ));
} void addEdge(int u, int v, int w) {
es[++ce] = Edge(v, h[u], w);
h[u] = ce;
} Edge& operator [] (int pos) {
return es[pos];
}
}MapManager; #define ll long long const signed ll llf = (signed ll) ((~0ull) >> ); int n;
int ccir, cc;
MapManager g;
stack<int> s;
boolean *vis, *icir;
int *cir, *nw;
ll *ap[], *cp[], *dep, *dis; inline void init() {
scanf("%d", &n);
vis = new boolean[(n + )];
icir = new boolean[(n + )];
cir = new int[(n + )];
nw = new int[(n + )];
dep = new ll[(n + )];
dis = new ll[(n + )];
for (int i = ; i < ; i++) {
ap[i] = new ll[(n + )];
cp[i] = new ll[(n + )];
}
g = MapManager(n, n << );
memset(vis, false, sizeof(boolean) * (n + ));
memset(icir, false, sizeof(boolean) * (n + ));
for (int i = , u, v, w; i <= n; i++) {
scanf("%d%d%d", &u, &v, &w);
g.addEdge(u, v, w);
g.addEdge(v, u, w);
}
} boolean getLoop(int p, int fa) {
if (vis[p]) {
ccir = ;
int cur = ;
do {
cur = s.top();
s.pop();
icir[cur] = true;
cir[ccir++] = cur;
cc = ccir - ;
} while (cur != p);
return true;
}
vis[p] = true;
s.push(p);
for (int i = g.h[p]; ~i; i = g[i].nx) {
int e = g[i].ed;
if (e == fa) continue;
if (getLoop(e, p)) {
if (icir[p]) {
nw[cc] = g[i].w;
cc = (cc + ) % ccir;
}
return true;
}
}
s.pop();
return false;
} void dfs(int p, int fa, ll dep, int& fn, ll& fd) {
if (dep > fd)
fd = dep, fn = p;
for (int i = g.h[p]; ~i; i = g[i].nx) {
int e = g[i].ed;
if (e == fa || icir[e]) continue;
dfs(e, p, dep + g[i].w, fn, fd);
}
} inline void solve() {
getLoop(, );
ll fixedd = ;
// for (int i = 0; i < ccir; i++)
// cerr << cir[i] << " ";
// cerr << endl;
// for (int i = 0; i < ccir; i++)
// cerr << nw[i] << " ";
// cerr << endl;
for (int i = , fn, fbn; i < ccir; i++) {
fn = -, dep[i] = ;
dep[i] = , dfs(cir[i], , , fn, dep[i]);
if (~fn)
icir[cir[i]] = false, dfs(fn, , , fbn, fixedd), icir[cir[i]] = true;
}
dis[] = ;
for (int i = ; i < ccir; i++)
dis[i] = nw[i - ];
for (int i = ; i < ccir; i++)
dis[i] += dis[i - ];
ll mi = dep[];
ap[][] = -llf, cp[][] = dep[];
for (int i = ; i < ccir; i++) {
ap[][i] = max(ap[][i - ], dep[i] + dis[i] + mi);
mi = max(mi, dep[i] - dis[i]);
cp[][i] = max(cp[][i - ], dep[i] + dis[i]);
}
mi = dep[ccir - ] + dis[ccir - ];
ap[][ccir - ] = -llf, cp[][ccir - ] = dep[ccir - ];
for (int i = ccir - ; ~i; i--) {
ap[][i] = max(ap[][i + ], dep[i] - dis[i] + mi);
mi = max(mi, dep[i] + dis[i]);
cp[][i] = max(cp[][i + ], dep[i] + dis[ccir - ] - dis[i]);
}
ll ans = ap[][ccir - ];
for (int i = ; i < ccir - ; i++)
ans = min(max(max(ap[][i], ap[][i + ]), cp[][i] + cp[][i + ] + nw[ccir - ]), ans);
printf(Auto, max(ans, fixedd));
} int main() {
init();
solve();
return ;
}

Codeforces 835F Roads in the Kingdom - 动态规划的更多相关文章

  1. Codeforces 835F Roads in the Kingdom (环套树 + DP)

    题目链接 Roads in the Kingdom 题意  给出一个环套树的结构,现在要删去这个结构中的一条边,满足所有点依然连通. 删边之后的这个结构是一棵树,求所有删边情况中树的直径的最小值. 显 ...

  2. 【CodeForces】835F Roads in the Kingdom

    一.题目 题目描述 王国有\(n\)座城市与\(n\)条有长度的街道,保证所有城市直接或间接联通,我们定义王国的直径为所有点对最短距离中的最大值,现因财政危机需拆除一条道路并同时要求所有城市仍然联通, ...

  3. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  4. Codeforces 835 F Roads in the Kingdom(树形dp)

    F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...

  5. codeforces 427 div.2 F. Roads in the Kingdom

    F. Roads in the Kingdom time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  6. Roads in the Kingdom CodeForces - 835F (直径)

    大意: 给定一个基环树, 求删除一条环上的边使得直径最小. 直径分两种情况 环上点延伸的树内的直径 两个环上点的树内深度最大的点匹配 第一种情况直接树形dp求一下, 第二种情况枚举删除的环边, 线段树 ...

  7. codeforces:Roads in the Kingdom分析和实现

    题目大意:国家有n个城市,还有n条道路,每条道路连通两个不同的城市,n条道路使得所有n个城市相互连通.现在国家经费不足,要关闭一条道路.国家的不便度定义为国家中任意两个不同的城市之间的距离的最大值,那 ...

  8. HDU 1025 Constructing Roads In JGShining's Kingdom[动态规划/nlogn求最长非递减子序列]

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  9. Codeforces 581F Zublicanes and Mumocrates - 树形动态规划

    It's election time in Berland. The favorites are of course parties of zublicanes and mumocrates. The ...

随机推荐

  1. OEMCC13.2 添加监控目标

    1.需求描述 2.添加数据库目标 2.1 部署AGENT   2.1.1 直接安装方式   2.1.2 离线安装方式   2.1.3 命令行安装方式 2.2 添加集群资源 2.3 添加数据库 3.添加 ...

  2. Installshield2015 定制安装在C:\Program files 目录 不正确问题

    情境描述:安装时,选择定制安装,安装目录选择C:\Program Files,安装后文件并没有到C:\Program Files,而是安装到了C:\Program Files (x86)目录下. 原因 ...

  3. Codeforces Round #402 D String Game(二分)

    [题目类型]二分答案 &题解: 只要你想到二分答案就不是难题了,但我当时确实是想不到. [时间复杂度]\(O(nlogn)\) &代码: #include <cstdio> ...

  4. python爬虫-基础入门-爬取整个网站《3》

    python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...

  5. python文件基础IO,OS

    #!/usr/bin/python # -*- coding: UTF-8 -*- import os # 导入 Phone 包 #File 对象方法: file对象提供了操作文件的一系列方法. #O ...

  6. linux下安装mysql等信息

    1.安装 apt-get update;// 第一次的时候,你更新一下你的软件包的源地址数据; apt-get install mysql-server 2.账号登陆 mysql -h localho ...

  7. python绝对路径的表述方式 及 字符串的转义

    当我们打开某文件的路径时,应该时刻注意绝对路径的表示方法,例如打开某个txt文件时 1, with open(‘d:\77\111.txt’) as  f: f.read() 此时会报错  ,路径被反 ...

  8. json为txt文本加密

    我们知道json是一种数据传输的加密格式 这里为txt格式的文本加密(纯属无聊)   写的比较凌乱,查找你输入的两个文件夹下面的所有txt文件(包含下一级文件): 运行时要注意,别把重要文件给加密了 ...

  9. 用 hashcat 破解 WIFI WPA2破解

    首先用CDlinux系统进行抓包,CDlinux抓包我就不详细说明 到这里可以查看如何安装CDlinux http://jingyan.baidu.com/article/7f766daf5173a9 ...

  10. flask模板结构组织(局部模板、宏、模板继承)

    模板结构组织 除了使用函数.过滤器等工具控制模板的输出外,jinja2还提供了一些工具来在宏观上组织模板内容. 局部模板 在Web程序中,我们通常会为每一类页面编写一个独立的模板.比如主页模板.用户资 ...