• [bzoj1086][SCOI2005][王室联邦] (树分块)


    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

    Solution

    新技能get,树分块

    大致做法如下,深搜整棵树,将沿路点入栈,若栈大小超过了B,则将超过B的部分点弹出,加入一个块,以当前点作为首都

    最后把为出栈元素再加入一个栈

    这样做块的大小一定不会超过3B

    0ms的程序,rank31

    //Kaiba_Seto 20170117
    //orz cjkmao
    #include <stdio.h>
    #include <string.h>
    #define MaxN 1010
    #define MaxBuf 1<<22
    #define RG register
    #define inline __inline__ __attribute__((always_inline))
    #define Blue() ((S == T&&(T=(S=B)+fread(B,1,MaxBuf,stdin),S == T)) ? 0 : *S++)
    
    char B[MaxBuf],*S=B,*T=B;
    
    template<class Type>inline void Rin(RG Type &x) {
        x=0;RG Type c=Blue(),f=1;
        for(; c<48||c>57; c=Blue())
            if(c==45)f=-1;
        for(; c>47&&c<58; c=Blue())
            x=(x<<1)+(x<<3)+c-48;
        x*=f; }
    
    bool vis[MaxN];
    
    int n,_b,_pb[MaxN],_pb_top,belong[MaxN],block_cnt,block_cap[MaxN];
    
    struct p {
        p *n; int t; }*f[MaxN];
    
    inline void link(RG int x,RG int y) {
        static p mem[MaxN<<1],*top=mem;
        *++top=(p) {f[x],y},f[x]=top;
        *++top=(p) {f[y],x},f[y]=top; }
    
    void dfs(RG int x) {
        vis[x]=1;
        RG size_t status=_pb_top;
        for(RG p *j=f[x]; j; j=j->n)
            if(!vis[j->t]) {
                dfs(j->t);
                if(_pb_top-status >= _b) {
                    block_cap[++block_cnt]=x;
                    while(_pb_top != status) {
                        RG int t=_pb[_pb_top--];
                        belong[t]=block_cnt; } } }
        _pb[++_pb_top]=x; }
    
    inline void block_solve() {
        dfs(1);
        while(_pb_top) {
            RG int t=_pb[_pb_top--];
            belong[t]=block_cnt; } }
    
    int main() {
        Rin(n),Rin(_b);
        for(RG int i=1; i<n; i++) {
            RG int x,y;
            Rin(x),Rin(y);
            link(x,y); }
        block_solve();
        printf("%d
    ",block_cnt);
        for(RG int i=1; i<=n; i++)
            printf("%d%c",belong[i],i==n?'
    ':' ');
        for(RG int i=1; i<=block_cnt; i++)
            printf("%d%c",block_cap[i],i==block_cnt?'
    ':' ');
        fclose(stdin);
        return 0; }
  • 相关阅读:
    mysql 函数 存储过程 事件(event) job 模板
    protobuf 无proto 解码 decode 语言 java python
    mitmproxy fiddler 抓包 填坑
    android adb 常用命令
    android机器人 模拟 踩坑过程
    RabbitMQ添加新用户并支持远程访问
    Windows下RabbitMQ安装及配置
    Java mybatis mysql 常用数据类型对应关系
    easyExcel 踩坑
    linux防火墙查看状态firewall、iptable
  • 原文地址:https://www.cnblogs.com/keshuqi/p/6291671.html
Copyright © 2020-2023  润新知