bzoj1086【SCOI2005】王室联邦

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1086

sol  :这题水水啊,直接大力DFS就行了

   首先当且仅当x<B时无解

   对于以x为根的子树,如果未分配的siz[x]>B,则单独划出一个省

   其他未被分配的点随意就近分配就好了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int Mx=1010;
int n,k,top,ans,q[Mx],cap[Mx],belong[Mx],siz[Mx];
int tot,head[Mx],nxt[2*Mx],ver[2*Mx];
inline void add(int x,int y)
{
    nxt[++tot]=head[x];
    ver[tot]=y;
    head[x]=tot;
}
void dfs1(int x,int fa)
{
    q[++top]=x;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=ver[i];
        if(y!=fa)
        {
            dfs1(y,x);
            if(siz[x]+siz[y]>=k)
            {
                siz[x]=0;
                cap[++ans]=x;
                while(q[top]!=x) belong[q[top--]]=ans;
            }
            else siz[x]+=siz[y];
        }
    }
    siz[x]++;
}
void dfs2(int x,int fa,int tmp)
{
    if(belong[x]) tmp=belong[x];
    else belong[x]=tmp;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=ver[i];
        if(y!=fa)
            dfs2(y,x,tmp);
    }
}
void output()
{
    cout<<ans<<endl;
    for(int i=1;i<=n;i++) cout<<belong[i]<<" ";cout<<endl;
    for(int i=1;i<=ans;i++) cout<<cap[i]<<" ";cout<<endl;
}
int main() 
{
    scanf("%d%d",&n,&k);
    if(n<k) { cout<<"0"<<endl; return 0; }
    for(int i=1,x,y;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y),add(y,x);
    }
    dfs1(1,0); if(!ans) cap[++ans]=1;
    dfs2(1,0,ans);
    output();
    return 0;
}

 

posted @ 2017-02-28 15:38  Czarina  阅读(...)  评论(... 编辑 收藏