zoukankan      html  css  js  c++  java
  • bzoj 1086: [SCOI2005]王室联邦 (分块+dfs)

    Description

      “余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成
    员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条
    直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个
    城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经
    过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的
    你快帮帮这个国王吧!

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    3
    2 1 1 3 3 3 3 2
    2 1 8
     
    思路:
    在树上dfs从根节点往下遍历,如果遍历到某结点的几棵子树加起来大于B,那么就把这几棵子树里的点扔到一个块里面也就是归为一个省(因为计算子树大小是从下到上的所以不用担心大于3B),这个块的省会就是当前点,这样处理完后还会剩下一些大小小于B的子树,我们再进行一遍dfs,把这些树里的点扔到其他能扔的块里面去。
     
    实现代码;
    #include<bits/stdc++.h>
    using namespace std;
    const int M = 1e4+10;
    int n,B,tot,cnt,top;
    int head[M],siz[M],gen[M],blo[M],q[M];
    
    struct node{
        int to,next;
    }e[M];
    
    void add(int u,int v){
        e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt;
    }
    
    void dfs(int u,int fa){
        q[++top] = u;
        for(int i = head[u];i;i=e[i].next){
            int v = e[i].to;
            if(v == fa) continue;
            dfs(v,u);
            if(siz[u] + siz[v] >= B){
                siz[u] = 0;
                gen[++tot] = u;
                while(q[top]!=u)
                    blo[q[top--]] = tot;
            }
            else
                siz[u] += siz[v];
        }
        siz[u] ++;
    }
    
    void dfs1(int u,int fa,int c){
        if(blo[u]) c = blo[u];
        else blo[u] = c;
        for(int i = head[u];i;i=e[i].next){
            int v = e[i].to;
            if(v == fa) continue;
            dfs1(v,u,c);
        }
    }
    
    int main()
    {
        int u,v;
        scanf("%d%d",&n,&B);
        if(n < B){
            printf("0
    "); return 0;
        }
        for(int i = 2;i <= n;i ++){
            scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        dfs(1,0);
        if(tot == 0) gen[++tot] = 1;
        dfs1(1,0,tot);
        printf("%d
    ",tot);
        for(int i = 1;i <= n;i ++)
            printf("%d ",blo[i]);
        printf("
    ");
        for(int i = 1;i <= tot;i ++)
            printf("%d ",gen[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/kls123/p/9942723.html
Copyright © 2011-2022 走看看