[題解]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

王室聯邦分塊大法好!%%%PoPoQQQ

代碼:

#include<cstdio>
#include<algorithm>
using namespace std;

template<typename T>inline void read(T &x){
    T f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    x*=f;
}

const int maxn=1010;
struct edge{
    int to,nxt;
}e[maxn<<1];
int n,B,num,sta[maxn],top,bel[maxn];
int head[maxn],pro[maxn];

void add(int u,int v){
    e[++num].to=v;e[num].nxt=head[u];head[u]=num;
    e[++num].to=u;e[num].nxt=head[v];head[v]=num;
}
void Dfs(int x,int fa){
    int bot=top;
    for(int i=head[x];i;i=e[i].nxt){
        if(e[i].to==fa)continue;
        Dfs(e[i].to,x);
        if(top-bot>=B){
            pro[++pro[0]]=x;
            while(top>bot)
                bel[sta[top--]]=pro[0];
        }
    }
    sta[++top]=x;
}

int main(){
    read(n);read(B);
    for(int i=1,u,v;i<n;i++){
        read(u);read(v);
        add(u,v);
    }
    Dfs(1,0);
    while(top)bel[sta[top--]]=pro[0];
    printf("%d\n",pro[0]);
    for(int i=1;i<=n;i++)printf("%d ",bel[i]);
    putchar(10);
    for(int i=1;i<=pro[0];i++)printf("%d ",pro[i]);
    putchar(10);
    return 0;
}
發佈了81 篇原創文章 · 獲贊 43 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章