来自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 ",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; }