[CF321C]Ciel the Commander
题目大意:
给你一棵n个结点的树,给每个结点分级,最高为'A',最低为'Z'。
尝试构造一种分级方案,使得任意两个相同级别的结点路径上至少有一个更高级的结点。
思路:
贪心+树上点分。
递归处理每一棵子树。
对于每次处理的子树,把重心分成尽量高的级别。
最后判一下够不够分。
1 #include<cstdio> 2 #include<cctype> 3 #include<vector> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int inf=0x7fffffff; 12 const int N=100001; 13 std::vector<int> e[N]; 14 inline void add_edge(const int &u,const int &v) { 15 e[u].push_back(v); 16 e[v].push_back(u); 17 } 18 char lev[N]; 19 int size[N]={inf},center,min,size_tree; 20 char max_level; 21 bool mark[N]; 22 void getsize(const int &x,const int &par) { 23 size[x]=1; 24 for(unsigned i=0;i<e[x].size();i++) { 25 const int &y=e[x][i]; 26 if(y==par||mark[y]) continue; 27 getsize(y,x); 28 size[x]+=size[y]; 29 } 30 } 31 void dfs(const int &x,const int &par) { 32 size[x]=1; 33 int tmp=0; 34 for(unsigned i=0;i<e[x].size();i++) { 35 const int &y=e[x][i]; 36 if(y==par||mark[y]) continue; 37 dfs(y,x); 38 tmp=std::max(tmp,size[y]); 39 size[x]+=size[y]; 40 } 41 tmp=std::max(tmp,size_tree-size[x]); 42 if(tmp<min) { 43 min=tmp; 44 center=x; 45 } 46 } 47 inline int find(const int &x) { 48 min=inf; 49 size_tree=size[x]; 50 dfs(x,0); 51 return center; 52 } 53 void solve(const int &x,const char &level) { 54 getsize(x,0); 55 int center=find(x); 56 mark[center]=true; 57 lev[center]=level; 58 max_level=std::max(max_level,level); 59 for(unsigned i=0;i<e[center].size();i++) { 60 const int &y=e[center][i]; 61 if(mark[y]) continue; 62 solve(y,level+1); 63 } 64 } 65 int main() { 66 const int n=getint(); 67 for(register int i=1;i<n;i++) { 68 add_edge(getint(),getint()); 69 } 70 solve(1,'A'); 71 if(max_level>'Z') { 72 puts("Impossible!"); 73 } else { 74 for(register int i=1;i<=n;i++) { 75 printf("%c%c",lev[i]," \n"[i==n]); 76 } 77 } 78 return 0; 79 }