zoukankan      html  css  js  c++  java
  • BZOJ 1086 王室联邦 | BFS

    BZOJ 1086 王室联邦

    题意

    把一棵树分块,每块大小在[B, 3B]之间(B由输入数据给出),每个块需要对应一个核心点,核心点可以在块内,这个点要满足块内每个点到核心点的路径上的点都属于这个块(核心点本身不算),请输出分块方案。

    题解

    VFK的糖果公园题解让我先来把这道题做了……

    做法:直接BFS。

    显然我们需要维护一个栈来存储节点编号。
    对于一个子树u, 记录刚进入子树时的top,然后BFS所有子树,每当BFS完一个子树并发现新top - 原top >= B时,就把旧top以上的所有点弹出作为一个块,核心点是当前子树的根节点u。
    注意最后可能有一块与根节点相连的部分没有归到任何块里,把它归到最后一个块中。

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    template <class T>
    void read(T &x){
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
    	if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
    	x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x){
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    #define space putchar(' ')
    #define enter putchar('
    ')
    
    const int N = 1005;
    int n, B, stk[N], top, bel[N], cap[N], idx;
    int ecnt, adj[N], nxt[2*N], go[2*N];
    
    void add(int u, int v){
        go[++ecnt] = v;
        nxt[ecnt] = adj[u];
        adj[u] = ecnt;
    }
    void dfs(int u, int pre){
        int st = top;
        for(int e = adj[u], v; e; e = nxt[e])
    	if(v = go[e], v != pre){
    	    dfs(v, u);
    	    if(top - st >= B){
    		cap[++idx] = u;
    		while(top > st) bel[stk[top--]] = idx;
    	    }
    	}
        stk[++top] = u;
    }
    
    int main(){
    
        read(n), read(B);
        for(int i = 1, u, v; i < n; i++)
    	read(u), read(v), add(u, v), add(v, u);
        dfs(1, 0);
        while(top) bel[stk[top--]] = idx;
        write(idx), enter;
        for(int i = 1; i <= n; i++)
    	write(bel[i]), i == n ? enter : space;
        for(int i = 1; i <= idx; i++)
    	write(cap[i]), i == idx ? enter : space;
    
        return 0;
    }
    
  • 相关阅读:
    2019年----沉淀的一年
    条目八《永不建立auto_ptr的容器》
    条目七《如果容器中包含了通过new操作创建的指针,切记在容器对象析构前将指针delete掉》
    条目六《当心C++编译器中最烦人的分析机制》
    条目五《尽量使用区间成员函数代替它们的单元素兄弟》
    cpu上下文切换
    条目四《用empty来代替检查size()是否为0》
    条目三《确保容器中的副本对象高效而正确》
    ORB与LBP、HOG
    C++
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/BZOJ1086.html
Copyright © 2011-2022 走看看