zoukankan      html  css  js  c++  java
  • 【bzoj1086】[SCOI2005]王室联邦 树分块

    题目描述

    将一棵n个点的树分为若干“块”,每个块满足:大小在B到3B之间,并且这个“块”添加某个点后连通。求方案。

    输入

    第一行包含两个数N,B(1<=N<=1000, 1 <= B <= N)。接下来N-1行,每行描述一条边,包含两个数,即这条边连接的两个城市的编号。

    输出

    如果无法满足国王的要求,输出0。否则输出数K,表示你给出的划分方案中省的个数,编号为1..K。第二行输出N个数,第I个数表示编号为I的城市属于的省的编号,第三行输出K个数,表示这K个省的省会的城市编号,如果有多种方案,你可以输出任意一种。

    样例输入

    8 2
    1 2
    2 3
    1 8
    8 7
    8 6
    4 6
    6 5

    样例输出

    3
    2 1 1 3 3 3 3 2
    2 1 8


    题解

    树分块

    给树分块的方法:

    对原树进行DFS,维护一个栈,当DFS到每个点时记录栈顶位置。

    当处理完某个子节点时,如果当前栈顶位置与原来位置相差大于等于B,则将它们之间的点分为一块。最后把这个点压入栈中。

    最后DFS完整棵树后,栈中剩余的点放到最后一块中。

    证明可以参考 VFK’s Blog

    时间复杂度$O(n)$

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 1010
    using namespace std;
    int b , head[N] , to[N << 1] , next[N << 1] , cnt , sta[N] , top , bl[N] , v[N] , num;
    void add(int x , int y)
    {
    	to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
    }
    void dfs(int x , int fa)
    {
    	int i , now = top;
    	for(i = head[x] ; i ; i = next[i])
    	{
    		if(to[i] != fa)
    		{
    			dfs(to[i] , x);
    			if(top - now >= b)
    			{
    				v[++num] = x;
    				while(top != now) bl[sta[top -- ]] = num;
    			}
    		}
    	}
    	sta[++top] = x;
    }
    int main()
    {
    	int n , i , x , y;
    	scanf("%d%d" , &n , &b);
    	for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x);
    	dfs(1 , 0);
    	while(top) bl[sta[top -- ]] = num;
    	printf("%d
    " , num);
    	for(i = 1 ; i <= n ; i ++ ) printf("%d " , bl[i]);
    	printf("
    ");
    	for(i = 1 ; i <= num ; i ++ ) printf("%d " , v[i]);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    《学习OpenCV》练习题第五章第二题abc
    《学习OpenCV》练习题第五章第一题ab
    《学习OpenCV》练习题第四章第八题ab
    《学习OpenCV》练习题第四章第三题b
    《学习OpenCV》练习题第四章第三题a
    《学习OpenCV》练习题第四章第二题
    《学习OpenCV》练习题第四章第一题b&c
    《学习OpenCV》练习题第四章第一题a
    《学习OpenCV》练习题第四章第七题abc
    【T^T 1736】【FJUTOJ 1077】排座位
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7741675.html
Copyright © 2011-2022 走看看