zoukankan      html  css  js  c++  java
  • Bzoj1086 [SCOI2005]王室联邦

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
    Submit: 1749  Solved: 1056

    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

    HINT

     

    Source

    树 贪心 (伪)树分块

    听说是树分块裸题……喜+1系列

    按DFS序遍历整棵树,发现子树大小大于B,就把它们划成一块

    这样分出来,每棵子树的大小都在B~2B之间。

    最后还会剩下一些零碎的结点,它们的总数小于B(不然就被划分了),把它们拼到最近的块里,该块尺寸不会超过3B,满足要求。

    n<B时无解

    写啥WA啥系列,34行把cnt写成u挂了一次

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 using namespace std;
     7 const int mxn=2010;
     8 int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
    12     return x*f;
    13 }
    14 struct edge{
    15     int v,nxt;
    16 }e[mxn<<1];
    17 int hd[mxn],mct=0;
    18 void add_edge(int u,int v){
    19     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
    20 }
    21 //
    22 int n,B;
    23 int t[mxn],C[mxn],sz[mxn];
    24 int st[mxn],top=0,cnt=0;
    25 void DFS(int u,int fa){
    26     st[++top]=u;
    27     for(int i=hd[u],v;i;i=e[i].nxt){
    28         v=e[i].v;
    29         if(v==fa)continue;
    30         DFS(v,u);
    31         if(sz[u]+sz[v]>=B){
    32             C[++cnt]=u;
    33             while(st[top]!=u){
    34                 t[st[top--]]=cnt;
    35             }
    36             sz[u]=0;
    37         }
    38         else sz[u]+=sz[v];
    39     }
    40     ++sz[u];
    41     return;
    42 }
    43 void DFS2(int u,int fa,int c){
    44     if(!t[u])t[u]=c;
    45     else c=t[u];
    46     for(int i=hd[u];i;i=e[i].nxt){
    47         if(e[i].v==fa)continue;
    48         DFS2(e[i].v,u,c);
    49     }
    50     return;
    51 }
    52 int main(){
    53     int i,j,u,v;
    54     n=read();B=read();
    55     if(n<B){printf("0
    ");return 0;}
    56     for(i=1;i<n;i++){
    57         u=read();v=read();
    58         add_edge(u,v);add_edge(v,u);
    59     }
    60     DFS(1,0);
    61     //
    62     if(!cnt){C[cnt=1]=1;}
    63     DFS2(1,0,cnt);
    64     printf("%d
    ",cnt);
    65     for(i=1;i<=n;i++){printf("%d ",t[i]);}printf("
    ");
    66     for(i=1;i<=cnt;i++){printf("%d ",C[i]);}printf("
    ");
    67     return 0;
    68 }
  • 相关阅读:
    python模块搜索路径
    Python数据结构
    Python文件类型
    Python循环语句
    Python条件语句
    python配置文件操作——configparser模块
    python 加密方式(MD5&sha&hashlib)
    python MySQL 获取全部数据库(DATABASE)名、表(TABLE)名
    python sqlite3查看数据库所有表(table)
    027.MFC_映射消息
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6618751.html
Copyright © 2011-2022 走看看