[SCOI2005]王室联邦

[SCOI2005]王室联邦 

类似树分块

>=B,并且<=3B

直接dfs,用一个全局栈记录未规定省份的元素

dfs(y)上来,如果栈内元素>=B,就弹出来变成一个省,并且省会是x(x不在该省内)

从x回溯前把x加入栈内

这样,每个省的大小其实<=2*B-1(B-1+B)

最后会剩下和1相连的一些,总大小最多是B

必然有一个元素和最后一个省相邻

直接并入最后一个省即可

 

数据中没有无解的情况

无解的话也就是n<B?

n=B的情况其实要特判的。但是数据水233333

 

复杂度O(n)

 代码:

#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1005;
int n,B;
struct node{
    int nxt,to;
}e[2*N];
int hd[N],cnt;
void add(int x,int y){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    hd[x]=cnt;
}
int sta[N],top;
int be[N],rt[N];
int tot;
void dfs(int x,int fa){
    int now=top;
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa) continue;
        dfs(y,x);
        if(top-now>=B){
            rt[++tot]=x;
            while(top!=now) be[sta[top--]]=tot;
        }
    }
    sta[++top]=x;
}
int main(){
    rd(n);rd(B);
    int x,y;
    for(reg i=1;i<n;++i){
        rd(x);rd(y);
        add(x,y);add(y,x);
    }
    dfs(1,0);
    while(top) be[sta[top--]]=tot;
    printf("%d\n",tot);
    for(reg i=1;i<=n;++i){
        printf("%d ",be[i]);
    }puts("");
    for(reg i=1;i<=tot;++i){
        printf("%d ",rt[i]);
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/2/1 10:42:10
*/

 

posted @ 2019-02-01 11:00  *Miracle*  阅读(214)  评论(0编辑  收藏  举报