`
阿尔萨斯
  • 浏览: 4471667 次
社区版块
存档分类
最新评论

zoj 3820 Building Fire Stations(二分+bfs)

 
阅读更多

题目链接: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版本

    zoj_1004.cpp 求单词字母进出栈后能形成目标串的进出方案 广度优先搜索求解

    ZOJ1055-Oh_Those_Achin_Feet.rar_BFS最短路径_ZOJ1055_bfs求最短路径_zoj

    在标签中,"bfs最短路径"和"zoj1055 bfs求最短路径"进一步强调了题目要求用BFS算法来求解图中的最短路径问题。ZOJ1055这个标签则直接指向了该编程挑战。 在压缩包内的文件"1055-Oh,Those Achin'Feet.cpp"是一个C++...

    ZOJ1002 Fire Net

    NULL 博文链接:https://weitch.iteye.com/blog/1006972

    ZOJ1001 A + B Problem

    【ZOJ1001 A + B Problem】是在线判题系统ZOJ(Zhejiang Online Judge)上的一道编程题目。这道题目通常作为入门级别的算法问题,目的是让初学者熟悉在线判题系统的提交流程以及基本的编程概念。题目要求编写一个...

    浙江大学ZOJ题目分类

    浙江大学ZOJ题目分类旨在为编程学习者提供一个系统化的训练平台,帮助他们在算法和编程技能上实现质的飞跃。ZOJ平台提供的分类题目包括但不限于基础算法、数据结构、动态规划以及模拟问题等,这些分类覆盖了计算机...

    zoj 1002_zoj1002_

    【标题】"ZOJ 1002" 是一个在线编程竞赛题目,源自ZOJ(Zhejiang Online Judge),这是一个面向ACM/ICPC(国际大学生程序设计竞赛)的在线评测系统。题目编号1002,通常表示该题是ZOJ平台上的一个问题,可能涉及算法...

    acm.tar.gz_zoj_zoj题解_题目分类

    9. 排序和搜索:快速排序、归并排序、二分查找等,这些都是算法中的基本操作。 难易度的划分则可能基于题目所需的时间复杂度、空间复杂度、解题思路的复杂性等因素。初级题目通常是基础概念和算法的运用,适合初学...

    zoj1002 C语言

    zoj 1002 C语言的为什么描述要这么多字啊。。

    zoj 源码700题

    3. **算法与数据结构**:700题涵盖的范围广泛,涉及基本的排序算法(如冒泡、快速、归并排序),查找算法(如二分查找),以及高级算法如动态规划(如斐波那契数列、背包问题)、图论(如最短路径、最小生成树)、...

    ACM训练必备POJ ZOJ题目分类及解题思路

    学习ACM程序设计的朋友一定要看,这是训练必备的POJ ZOJ题目分类及解题思路

    zoj 分类加题解(浙大ACM)

    《ZOJ ACM分类加题解》是针对浙江大学ACM竞赛训练平台的一份宝贵资源,它包含了大量的编程竞赛题目和相应的解答。这份资料旨在帮助参赛者提升算法能力,提高解决实际问题的技巧,无论是在无网络环境下还是有网络时,...

    ZOJ1004回溯+深搜

    深度搜索 回溯 int main { string s1 s2; while cin &gt;&gt; s1 &gt;&gt; s2 { count 0; cout &lt;&lt; &quot;[&quot; &lt;&lt; endl; if s1 length s2 length BackTrake s1 s2 ;... [更多]

    zoj.gz_ ZOJ_ZOJ 1016_max flow_zoj 1045_zoj.rar

    标题中的"ZOJ.gz_ ZOJ_ZOJ 1016_max flow_zoj 1045_zoj.rar" 提到了两个ZOJ(Zhejiang Online Judge)的题目,分别是1016和1045,这两个数字通常代表在线编程竞赛中的题目编号。这些题目通常涉及到算法和数据结构的...

    ZOJ:浙江大学程序在线评测系统.docx

    ZOJ,全称“浙江大学程序在线评测系统”(Zhejiang University Online Judge),是一个提供信息学(算法竞赛)题库及程序评测的网站。以下是关于ZOJ的详细介绍: 一、基本信息 名称:浙江大学程序在线评测系统(ZOJ)...

    zoj 3590 -3+1.md

    zoj 3590 -3+1.md

    ZOJ题目答案源码

    首先,我们可以从这些源代码中学习到基础的算法思想,如排序算法(快速排序、归并排序、冒泡排序、插入排序等)、搜索算法(二分查找、深度优先搜索、广度优先搜索等)。这些算法是解决问题的基本工具,理解和掌握...

    pku hdu zoj题目分类

    "POJ 计算几何入门题目.doc"可能介绍了计算几何的基础知识,并提供了一些实践题目,这个领域涉及点、线、面的相互关系,以及在二维和三维空间中的几何操作。 5. **ZOJ题目分类**: "zoj题目分类.doc"对应浙江大学...

    ZOJ月赛 题解 (ZOJ Monthly, August 2014)

    **ZOJ月赛题解 (ZOJ Monthly, August 2014)** ZOJ(Zhejiang Online Judge)是中国著名的在线编程竞赛平台之一,它为程序员和学生提供了丰富的算法练习和比赛机会。2014年8月的ZOJ月赛是一场面向广大编程爱好者的...

    Problem Arrangement zoj 3777

    Problem Arrangement zoj 3777

    zoj1027解题指南

    【标题】"ZOJ1027解题指南"是一个针对特定编程竞赛题目——ZOJ1027的解决方案集合。ZOJ,全称为“Zhejiang Online Judge”,是浙江大学主办的一个在线编程竞赛平台,提供了丰富的算法题目供参赛者练习和挑战。本解题...

Global site tag (gtag.js) - Google Analytics