SCOI2005王室联邦(树分块,搜索)

王室联邦

【题意】树分块。求共有多少子树规模在\((B,3B)\)

【解题】dfs 或 bfs,用栈维护。

#include <cstdio>
#include<iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 105000;
int n, B, stk[N], top, bel[N], cap[N], idx, len,head[N];
int ecnt, adj[N], nxt[2*N], go[2*N];
struct node{
   int v,from,w,next,to;
}e[N];
void add(int u, int v){
      e[++len].next = head[u];
      head[u] = len;
      e[len].to = v;
      e[len].from = u;
}

void dfs(int u, int pre){
    int st = top;
    for(int z = head[u], v; z; z = e[z].next)
    if(v = e[z].to, v != pre){
        dfs(v, u);
        if(top - st >= B){
        cap[++idx] = u;  //省会 
        while(top > st) bel[stk[top--]] = idx;  //各城市所属的省 
        }
    }
    stk[++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) bel[stk[top--]] = idx;  //剩下的那坨都是最后一个省的 
    cout << idx << endl;
     
    for(int i = 1; i <= n; i++)
       printf("%d ",bel[i]);
    puts("");
    for(int i = 1; i <= idx; i++)
       printf("%d ",cap[i]);
    puts("");

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/phemiku/p/11809727.html