BZOJ 1086 & 类树的分块
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1086 & 类树的分块相关的知识,希望对你有一定的参考价值。
题意:
“余”人国的国王想重新编制他的 国家。他想把他的国家划分成若干个省,每个省都由他们王室联邦的一个成员来管理。他的国家有n个城市,编号为1..n。一些城市之间有道路相连,任意两个 不同的城市之间有且仅有一条直接或间接的道路。为了防止管理太过分散,每个省至少要有B个城市,为了能有效的管理,每个省最多只有3B个城市。每个省必须 有一个省会,这个省会可以位于省内,也可以在该省外。但是该省的任意一个城市到达省会所经过的道路上的城市(除了最后一个城市,即该省省会)都必须属于该 省。一个城市可以作为多个省的省会。聪明的你快帮帮这个国王吧!
sol:
膜拜popoqqq大神犇...题解非常直观清晰...附个链接好了...http://blog.csdn.net/popoqqq/article/details/42772237
code:
/************************************************************** Problem: 1086 User: YCuangWhen Language: C++ Result: Accepted Time:12 ms Memory:3616 kb ****************************************************************/ /*========================================================================== # Last modified: 2016-02-29 14:01 # Filename: 1086.cpp # Description:树的分块 ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 100000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long ll; typedef unsigned long long ull; template<class T> inline void read(T& num) { bool start=false,neg=false; char c; num=0; while((c=getchar())!=EOF) { if(c==‘-‘) start=neg=true; else if(c>=‘0‘ && c<=‘9‘) { start=true; num=num*10+c-‘0‘; } else if(start) break; } if(neg) num=-num; } /*==================split line==================*/ int top=0,sume=0; int n,b,cnt=0; int to[maxm],belong[maxn],next[maxm],first[maxn]; int s[maxm],root[maxn]; void addedge(int x,int y){ sume++; to[sume]=y; next[sume]=first[x]; first[x]=sume; } void dfs(int node,int fa){ int bottom=top; for (int i=first[node];i!=-1;i=next[i]) if (to[i]!=fa){ dfs(to[i],node); if (top-bottom>=b){ root[++cnt]=node; while (top!=bottom) belong[s[top--]]=cnt; } } s[++top]=node; } int main(){ read(n); read(b); FORP(i,1,n) first[i]=-1; FORP(i,1,n-1) { int x,y; read(x); read(y); addedge(x,y); addedge(y,x); } dfs(1,0); while (top) belong[s[top--]]=cnt; printf("%d\n",cnt); FORP(i,1,n) printf("%d ",belong[i]); printf("\n"); FORP(i,1,cnt) printf("%d ",root[i]); }
以上是关于BZOJ 1086 & 类树的分块的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1086:[SCOI2005]王室联邦(DFS树分块)
「日常训练与知识学习」树的分块(王室联邦,HYSBZ-1086)