1086: [SCOI2005]王室联邦

来源:互联网 发布:深圳婚纱摄影排名 知乎 编辑:程序博客网 时间:2024/04/28 02:31

一开始做的时候脑残了,以为会出现很多无解的情况,于是加了一堆特判,果断WA。

后来发现,明明只有n<B的时候才无解啊。

然后发现题意理解错了。。。。

原来多颗子树可以由根连接成省,而根可以在省外。。。。。。。

于是我们有个贪心的方法。

当前节点的子树集的大小一旦大于等于B,直接分成一个省,当然我们还可以证明这个省的城市数<=2B。

最后还有一些<B的省,直接塞到别的省就好了。

#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct Edge{int to,next;}e[2010];int head[1005],cnt,k;void ins(int u,int v){cnt++;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}int B,sz[1005],q[1005],top,cap[1005],pro,belong[1005];void dfs(int u,int fa){q[++top]=u;for(int i=head[u];i;i=e[i].next){int v=e[i].to;if(v==fa)continue;dfs(v,u);if(sz[u]+sz[v]>=B){sz[u]=0;cap[++pro]=u;while(q[top]!=u)belong[q[top--]]=pro;}else sz[u]+=sz[v];}sz[u]++;}void set(int u,int fa,int anc){if(belong[u])anc=belong[u];else belong[u]=anc;for(int i=head[u];i;i=e[i].next){int v=e[i].to;if(v==fa)continue;set(v,u,anc);}}int main(){int n;scanf("%d%d",&n,&B);if(n<B){printf("0");return 0;}int u,v;for(int i=1;i<n;i++){scanf("%d%d",&u,&v);ins(u,v);ins(v,u);}dfs(1,0);if(!pro)cap[++pro]=1;set(1,0,pro);printf("%d\n",pro);for(int i=1;i<=n;i++)printf("%d ",belong[i]);printf("\n");for(int i=1;i<=pro;i++)printf("%d ",cap[i]); return 0;}


0 0
原创粉丝点击