• BZOJ1086 SCOI2005王室联邦


    想学树上莫队结果做了个树分块。

    看完题后想到了菊花图的形状认为无解,结果仔细一瞧省会可以在外省尴尬

    对于每一颗子树进行深搜,一旦遇到加在一起大小达到B则将它们并为一省,因为他子树搜完以后没有分出块的大小是小于B的,而且他自己当前剩下的也是小于B的,所以可以放心和。

    最后剩下的点肯定也小于B所以与最后一个省一合即可。当前子树根节点留给上面也是因为这个。

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1005;
     4 int bel[N],size[N],cap[N],head[N],num,cnt,top,s[N],n,b;
     5 struct node{
     6     int to,nex;
     7 }e[N<<1];
     8 void add(int x,int y)
     9 {
    10     e[++cnt].nex=head[x];e[cnt].to=y;head[x]=cnt;
    11 }
    12 void dfs(int x,int fa)
    13 {
    14     s[++top]=x;
    15     for(int i=head[x];i;i=e[i].nex)
    16     {
    17         int y=e[i].to;
    18         if(y==fa)continue;
    19         dfs(y,x);
    20         if(size[x]+size[y]>=b){
    21             size[x]=0;
    22             cap[++num]=x;
    23             while(s[top]!=x)bel[s[top--]]=num;
    24         }
    25         else size[x]+=size[y];
    26     }
    27     size[x]++;
    28 }
    29 int main()
    30 {
    31     scanf("%d%d",&n,&b);
    32     if(n<b){
    33         puts("0");return 0;
    34     }
    35     int x,y,w;
    36     for(int i=1;i<n;++i)
    37     {
    38         scanf("%d%d",&x,&y);
    39         add(x,y);add(y,x);
    40     }
    41     dfs(1,0);
    42     while(top)bel[s[top--]]=num;
    43     printf("%d
    ",num);
    44     for(int i=1;i<=n;++i)printf("%d ",bel[i]);
    45     printf("
    ");
    46     for(int i=1;i<=num;++i)printf("%d ",cap[i]);
    47     return 0;
    48 }
  • 相关阅读:
    Ubuntu下官方QQ崩溃的解决
    [转]PHP函数的实现原理及性能分析
    [收藏的资料]301重定向的实现方法
    手动配置Ubuntu 指定DNS服务器地址
    C# FTP操作类
    vs2010 快捷键大全
    分享一个不错的VS插件——CodeMap
    C# 快速的批量修改重命名.net程序的命名空间(一)转 tianyaxiang
    jquery 的 ajax 程序 简单的
    winform窗体间传值
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8350543.html
Copyright © 2020-2023  润新知