[bzoj1086][SCOI2005]王室联邦

来自FallDream的博客,未经允许,请勿转载,谢谢


余”人国的国王想重新编制他的国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成 员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个不同的城市之间有且仅有一条 直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个 城市。每个省必须有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经 过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该省。一个城市可以作为多个省的省会。聪明的 你快帮帮这个国王吧!1<=N<=1000, 1 <= B <= N

 

很有意思的题...大体就是直接dfs,在每次dfs的时候都处理一下子树的信息,把子树传回来的点加入一个栈里面,一满B个就划分一下,并且传回最后剩下的点。这样传回去的点不超过B-1个,每一次划分的不超过2B-2个,所以把根返回的直接塞进最后一个省里面就行了。

然后这道题貌似没有无解..

#include<iostream>
#include<cstdio>
#include<cstring>
#define MN 1000
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

int q[MN+5][MN+5],bel[MN+5],cap[MN+5],head[MN+5];
int b,n,tot=0,cnt=0,num,top[MN+5];
struct edge{int to,next;}e[MN*2+5];

void ins(int f,int t)
{
    e[++cnt]=(edge){t,head[f]};head[f]=cnt;
    e[++cnt]=(edge){f,head[t]};head[t]=cnt;
}

int dfs(int x,int fa)
{
    top[x]=0;
    for(int i=head[x];i;i=e[i].next)
    if(e[i].to!=fa)
    {
        dfs(e[i].to,x);
        if(top[x]>=b)
        {
            ++tot;cap[tot]=x;
            for(int j=1;j<=top[x];j++) bel[q[x][j]]=tot;
            top[x]=0;
        }
    }
    q[x][++top[x]]=x;
    for(int i=1;i<=top[x];i++) q[fa][++top[fa]]=q[x][i];
}

int main()
{
    n=read();b=read();
    for(int i=1;i<n;i++) ins(read(),read());    
    dfs(1,0);
    //if(!tot&&top[0]) return 0*puts("0");
    for(int i=1;i<=top[0];i++) bel[q[0][i]]=tot;
    printf("%d\n",tot);
    for(int i=1;i<=n;i++) printf("%d ",bel[i]); puts("");
    for(int i=1;i<=tot;i++) printf("%d ",cap[i]);
    return 0;
}

 

posted @ 2017-04-05 13:42  FallDream  阅读(...)  评论(... 编辑 收藏