2014牡丹江 区域赛 Building Fire Stations

给一棵最多2*10^5个结点的树,选择两个结点放置设备,要求所有结点其到最近设备的最远距离最小,求出这个最小距离。

最大值最小,首先想到二分。二分一个最大距离M,先以1号结点bfs出每个结点的深度。任选一个最大深度的结点,则离他距离M的父结点u上必须要放置一个设备。然后再以u进行bfs,同样的选择出第二个结点。再把选择的两个设备结点加入队列bfs,看是否能够遍历所有点,若能就满足。

zju上面做的,dfs会栈溢出。第一次以一号结点bfs可以预处理,之后直接取出最大深度的点就行。有可能两次找的放置设备的点相同,注意特判一下。二分过程完成后,有可能最后一次判断不成立,此时得到的两个设备的点不是题目所求,需要再判断一次。具体见代码。

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FF(i, a, b) for(int i = (a); i < (b); ++i)
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
//OTHER
#define PB push_back
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
typedef long long LL;
typedef unsigned long long ULL;
typedef vector <int> VI;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;
const int MOD = 1000000007;
const double PI = acos(-1.0);
const int maxn = 200010;

int n, M, rt1, rt2, mdrt;
VI G[maxn];
int num[maxn], fa[maxn], pre[maxn];
//指定深度任选的一个点,第一次bfs的父亲结点,第二次bfs父亲结点
bool vis[maxn];

void init()
{
    REP(i, n + 1)   G[i].clear();
}

struct Node{
    int id, d;
    Node() {}
    Node(int a, int b) : id(a), d(b) {}
}t;

int bfs(int s, int ff[])
{
    CLR(vis, 0);
    queue<Node> Q;
    Q.push(Node(s, 0));
    vis[s] = 1, ff[s] = 0;
    int md = 0;
    while (!Q.empty())
    {
        t = Q.front(); Q.pop();
        int u = t.id;
        num[t.d] = u;
        md = max(md, t.d);
        REP(i, G[u].size())
        {
            int v = G[u][i];
            if (!vis[v])
            {
                vis[v] = 1;
                ff[v] = u;
                Q.push(Node(v, t.d + 1));
            }
        }
    }
    return md;
}

int fun()    //标记两个设备能到达的点
{
    CLR(vis, 0);
    int cnt = 0;
    queue<Node> Q;
    vis[rt1] = vis[rt2] = 1;
    Q.push(Node(rt1, 0)), Q.push(Node(rt2, 0));
    while (!Q.empty())
    {
        t = Q.front(); Q.pop();
        if (t.d >= M)   continue;
        int u = t.id;
        REP(i, G[u].size())
        {
            int v = G[u][i];
            if (!vis[v])
            {
                vis[v] = 1;
                Q.push(Node(v, t.d + 1));
            }
        }
    }
    FE(i, 1, n)
        if (vis[i])
            cnt++;
    return cnt;
}

bool ok()
{
    rt1 = mdrt;
    REP(i, M)   rt1 = pre[rt1];
    int md = bfs(rt1, fa);
    rt2 = num[md];
    REP(i, M)   rt2 = fa[rt2];
    int cnt = fun();
    if (cnt >= n)
    {
        if (rt1 == rt2)     //特判两个点相等时
        {
            if (rt1 + 1 <= n)   rt2 = rt1 + 1;
            else        rt2 = rt1 - 1;
        }
        return 1;
    }
    return 0;
}

int main()
{
    int T, x, y;
    RI(T);
    while (T--)
    {
        RI(n);
        init();
        REP(i, n - 1)
        {
            RII(x, y);
            G[x].PB(y), G[y].PB(x);
        }
        int md = bfs(1, pre);
        mdrt = num[md];
        int L = 0, R = md;
        while (L <= R)
        {
            M = (L + R) >> 1;
            if (ok())  R = M - 1;
            else    L = M + 1;
        }
        M = L; ok();  //求得最小距离后再判断一次得出放置设备点
        printf("%d %d %d\n", L, rt1, rt2);
    }
    return 0;
}
/*
8
8
1 2
1 3
2 4
2 5
3 6
5 7
5 8
ans: 2 1 2
*/
				
时间: 2024-08-30 05:52:31

2014牡丹江 区域赛 Building Fire Stations的相关文章

2014牡丹江区域赛B(树的直径)ZOJ3820

Building Fire Stations Time Limit: 5 Seconds      Memory Limit: 131072 KB      Special Judge Marjar University is a beautiful and peaceful place. There are N buildings and N - 1 bidirectional roads in the campus. These buildings are connected by road

ACM学习历程——ZOJ 3829 Known Notation (2014牡丹江区域赛K题)(策略,栈)

Description Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expression follows all of its operands. Bob is a student in

ACM学习历程——ZOJ 3822 Domination (2014牡丹江区域赛 D题)(概率,数学递推)

Description Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboard with N rows and M columns. Every day after work, Edward will place

zoj 3822 Domination(2014牡丹江区域赛D题)

Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboar

zoj 3827 Information Entropy(2014牡丹江区域赛I题)

Information Entropy Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Information Theory is one of the most popular courses in Marjar University. In this course, there is an important chapter about information entropy. Entropy is t

ZOJ 3827 Information Entropy (2014牡丹江区域赛)

题目链接:ZOJ 3827 Information Entropy 根据题目的公式算吧,那个极限是0 AC代码: #include <stdio.h> #include <string.h> #include <math.h> const double e=exp(1.0); double find(char op[]) { if(op[0]=='b') return 2.0; else if(op[0]=='n') return e; else if(op[0]=='

zoj 3819(2014牡丹江区域赛 A题 )

题意:给出A班和B班的学生成绩,如果bob(A班的)在B班的话,两个班级的平均分都会涨.求bob成绩可能的最大,最小值. A班成绩平均值(不含BOB)>A班成绩平均值(含BOB) && B班成绩平均值(不含BOB)< B班成绩平均值(含BOB) 化简后得 B班成绩平均值(不含BOB) < X < A班成绩平均值(不含BOB) Sample Input 24 35 5 54 4 36 55 5 4 5 31 3 2 2 1Sample Output 4 42 4 1

2014牡丹江区域赛D(概率DP)ZOJ3822

Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headmaster of Marjar University. He is enthusiastic about chess and often plays chess with his friends. What's more, he bought a large decorative chessboar

2014牡丹江区域赛H(字典树)ZOJ3826

Hierarchical Notation Time Limit: 2 Seconds      Memory Limit: 131072 KB In Marjar University, students in College of Computer Science will learn EON (Edward Object Notation), which is a hierarchical data format that uses human-readable text to trans