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; }