题目链接:zoj 3820 Building Fire Stations
题目大意:给定一棵树,选取两个建立加油站,问说所有点距离加油站距离的最大值的最小值是多少,并且任意输出一种建立加油站的方式。
解题思路:二分距离判断,判断函数的复杂度是o(n),这样的复杂度应该是o(nlogn),即使常数系数偏大,但是居然跑了4.5s,也是醉了。
判断函数里面做了3次bfs,但是每次bfs节点最多遍历1次,首先任取一点做根建立一个树,找到深度最大的节点,以向上移动L(判断的ans)位置处的节点建立加油站,并以该点为根在建一棵树,这是第2次bfs,然后同样以最深的节点向上移动L次的节点建立加油站,判断这两个加油站使得所有节点距离加油站的值是否均小于等于L。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 200005;
const int INF = 0x3f3f3f3f;
int M, first[maxn], jump[maxn * 2], edge[maxn * 2];
int N, s, e, far[maxn], dis[maxn];
queue<int> que;
inline void add_edge(int u, int v) {
edge[M] = v;
jump[M] = first[u];
first[u] = M++;
}
void init () {
int l, r;
M = 0;
scanf("%d", &N);
memset(first, -1, sizeof(first));
for (int i = 1; i < N; i++) {
scanf("%d%d", &l, &r);
add_edge(l, r);
add_edge(r, l);
}
}
int bfs(int s) {
que.push(s);
dis[s] = far[s] = 0;
int u;
while (!que.empty()) {
u = que.front();
que.pop();
for (int i = first[u]; i + 1; i = jump[i]) {
int v = edge[i];
if (dis[v] > dis[u] + 1) {
far[v] = u;
dis[v] = dis[u] + 1;
que.push(v);
}
}
}
return u;
}
bool judge (int L) {
memset(dis, INF, sizeof(dis));
s = bfs(1);
for (int i = 0; i < L; i++) {
s = far[s];
if (far[s] == 0) {
e = s % N + 1;
return true;
}
}
memset(dis, INF, sizeof(dis));
e = bfs(s);
for (int i = 0; i < L; i++) {
if (far[e] == 0)
return true;
e = far[e];
}
if (e == s)
e = e % N + 1;
bfs(e);
for (int i = 1; i <= N; i++)
if (dis[i] > L)
return false;
return true;
}
void solve () {
if (N == 2) {
printf("0 1 2\n");
return ;
}
int l = 0, r = N;
while (l < r) {
int mid = (l + r) / 2;
if (judge(mid))
r = mid;
else
l = mid + 1;
}
judge(l);
printf("%d %d %d\n", l, s, e);
}
int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
init();
solve();
}
return 0;
}
分享到:
相关推荐
zoj_1004.cpp 求单词字母进出栈后能形成目标串的进出方案 广度优先搜索求解
在标签中,"bfs最短路径"和"zoj1055 bfs求最短路径"进一步强调了题目要求用BFS算法来求解图中的最短路径问题。ZOJ1055这个标签则直接指向了该编程挑战。 在压缩包内的文件"1055-Oh,Those Achin'Feet.cpp"是一个C++...
NULL 博文链接:https://weitch.iteye.com/blog/1006972
【ZOJ1001 A + B Problem】是在线判题系统ZOJ(Zhejiang Online Judge)上的一道编程题目。这道题目通常作为入门级别的算法问题,目的是让初学者熟悉在线判题系统的提交流程以及基本的编程概念。题目要求编写一个...
浙江大学ZOJ题目分类旨在为编程学习者提供一个系统化的训练平台,帮助他们在算法和编程技能上实现质的飞跃。ZOJ平台提供的分类题目包括但不限于基础算法、数据结构、动态规划以及模拟问题等,这些分类覆盖了计算机...
【标题】"ZOJ 1002" 是一个在线编程竞赛题目,源自ZOJ(Zhejiang Online Judge),这是一个面向ACM/ICPC(国际大学生程序设计竞赛)的在线评测系统。题目编号1002,通常表示该题是ZOJ平台上的一个问题,可能涉及算法...
9. 排序和搜索:快速排序、归并排序、二分查找等,这些都是算法中的基本操作。 难易度的划分则可能基于题目所需的时间复杂度、空间复杂度、解题思路的复杂性等因素。初级题目通常是基础概念和算法的运用,适合初学...
zoj 1002 C语言的为什么描述要这么多字啊。。
3. **算法与数据结构**:700题涵盖的范围广泛,涉及基本的排序算法(如冒泡、快速、归并排序),查找算法(如二分查找),以及高级算法如动态规划(如斐波那契数列、背包问题)、图论(如最短路径、最小生成树)、...
学习ACM程序设计的朋友一定要看,这是训练必备的POJ ZOJ题目分类及解题思路
《ZOJ ACM分类加题解》是针对浙江大学ACM竞赛训练平台的一份宝贵资源,它包含了大量的编程竞赛题目和相应的解答。这份资料旨在帮助参赛者提升算法能力,提高解决实际问题的技巧,无论是在无网络环境下还是有网络时,...
深度搜索 回溯 int main { string s1 s2; while cin >> s1 >> s2 { count 0; cout << "[" << endl; if s1 length s2 length BackTrake s1 s2 ;... [更多]
标题中的"ZOJ.gz_ ZOJ_ZOJ 1016_max flow_zoj 1045_zoj.rar" 提到了两个ZOJ(Zhejiang Online Judge)的题目,分别是1016和1045,这两个数字通常代表在线编程竞赛中的题目编号。这些题目通常涉及到算法和数据结构的...
ZOJ,全称“浙江大学程序在线评测系统”(Zhejiang University Online Judge),是一个提供信息学(算法竞赛)题库及程序评测的网站。以下是关于ZOJ的详细介绍: 一、基本信息 名称:浙江大学程序在线评测系统(ZOJ)...
zoj 3590 -3+1.md
首先,我们可以从这些源代码中学习到基础的算法思想,如排序算法(快速排序、归并排序、冒泡排序、插入排序等)、搜索算法(二分查找、深度优先搜索、广度优先搜索等)。这些算法是解决问题的基本工具,理解和掌握...
"POJ 计算几何入门题目.doc"可能介绍了计算几何的基础知识,并提供了一些实践题目,这个领域涉及点、线、面的相互关系,以及在二维和三维空间中的几何操作。 5. **ZOJ题目分类**: "zoj题目分类.doc"对应浙江大学...
**ZOJ月赛题解 (ZOJ Monthly, August 2014)** ZOJ(Zhejiang Online Judge)是中国著名的在线编程竞赛平台之一,它为程序员和学生提供了丰富的算法练习和比赛机会。2014年8月的ZOJ月赛是一场面向广大编程爱好者的...
Problem Arrangement zoj 3777
【标题】"ZOJ1027解题指南"是一个针对特定编程竞赛题目——ZOJ1027的解决方案集合。ZOJ,全称为“Zhejiang Online Judge”,是浙江大学主办的一个在线编程竞赛平台,提供了丰富的算法题目供参赛者练习和挑战。本解题...