• [SCOI2005]王室联邦


    题目描述

    “余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理。

    他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个城市。

    每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。

    一个城市可以作为多个省的省会。

    聪明的你快帮帮这个国王吧!

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    8 2 
    1 2 
    2 3 
    1 8 
    8 7 
    8 6 
    4 6 
    6 5 
    
    输出样例#1:
    3 
    2 1 1 3 3 3 3 2 
    2 1 8 
    
    树上分块
    如果有一个子树的数量大于b,那么就归入一个联通块
    最后剩余的城市全部塞进最后一个联通块
    可以证明不会大于3*b
    此题有spj,所以随便分
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 struct Node
     7 {
     8     int next,to;
     9 }edge[20001];
    10 int num,head[10001],n,b,cnt,size,root[100001],dfn[10001];
    11 int belong[10001];
    12 void add(int u,int v)
    13 {
    14     num++;
    15     edge[num].next=head[u];
    16     head[u]=num;
    17     edge[num].to=v;
    18 }
    19 void dfs(int x,int pa)
    20 {int i;
    21     int bottom=size;
    22     for (i=head[x];i;i=edge[i].next)
    23         {
    24             int v=edge[i].to;
    25             if (v==pa) continue;
    26             dfs(v,x);
    27             if (size-bottom>=b)
    28                 {
    29                     cnt++;
    30                     root[cnt]=x;
    31                     while (size>bottom)
    32                         {
    33                             belong[dfn[size--]]=cnt;
    34                         }
    35                 }
    36         }
    37     dfn[++size]=x;
    38 }
    39 int main()
    40 {int i,u,v;
    41     cin>>n>>b;
    42     for (i=1;i<=n-1;i++)
    43         {
    44             scanf("%d%d",&u,&v);
    45             add(u,v);add(v,u);
    46         }
    47     dfs(1,0);
    48     cout<<cnt<<endl;
    49     while (size)
    50         {
    51             belong[dfn[size--]]=cnt;
    52         }
    53     for (i=1;i<=n;i++)
    54         printf("%d ",belong[i]);
    55             cout<<endl;
    56     for (i=1;i<=cnt;i++)
    57         {
    58             printf("%d ",root[i]);
    59         }
    60 }
  • 相关阅读:
    python中如何将两个list合并成一个list,不用for语句
    python print的用法
    Pandas Timestamp 和 python 中 datetime 的互相转换
    python eval, exec. compile
    python 用 __all__ 暴露接口
    python functiontools 模块
    Python 修饰符, 装饰符
    Python 字典(Dictionary) update()方法
    Python :random 随机数生成
    Pandas dataframe 标记删除重复记录
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7603711.html
Copyright © 2020-2023  润新知