很巧的树上分块
/************************************************************** Problem: 1086 User: lxy8584099 Language: C++ Result: Accepted Time:84 ms Memory:1320 kb ****************************************************************/ /* 王室联邦 分块 (摘自谋博客 dfs 并且依次将儿子们的sta放入本次sta中 如果sta>B 那个这些城市为一个省 省会是目前节点 处理完后 没有分入省的城市返回到此节点的父节点继续判断 无解的情况 STL超空间。。。 手写队列。。。 */ #include<bits/stdc++.h> using namespace std; const int N=1050; struct pp {int v,nxt;} e[N<<1]; int head[N],tot,n,B,fa[N],res,sta[N],ans[N],top; void add(int u,int v) { e[++tot].nxt=head[u];head[u]=tot;e[tot].v=v; } void dfs(int u,int la) { int flag=top; for(int j=head[u];j;j=e[j].nxt) { int v=e[j].v; if(v==la) continue; dfs(v,u); if(top-flag>=B) { ans[++res]=u; while(top!=flag) fa[sta[top--]]=res; } } sta[++top]=u; } int main() { scanf("%d%d",&n,&B); for(int i=1,u,v;i<n;i++) { scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs(1,0); while(top) fa[sta[top--]]=res; // 补在最近的一个上面 printf("%d\n",res); for(int i=1;i<=n;i++) printf("%d ",fa[i]); printf("\n"); for(int i=1;i<=res;i++) printf("%d ",ans[i]); printf("\n"); return 0; }