zoukankan      html  css  js  c++  java
  • ZOJ

    ZOJ - 4045District Division

      题目大意:给你n个节点的树,然后让你划分这棵数使得,每一块都恰好k个节点并且两两间是连通的,也就是划分成n/k个连通集,如果可以输出YES,并输出对应的划分,否则输出NO

       一开始觉得是树形dp,但不知道如何下手,看大佬的做法才恍然大悟,其实就是找子树大小刚好是k的节点,刚让它作为这一分块的根节点,它的父节点就不再记录它的子树大小,详情见代码

     1 #include<cstdio>
     2 #include<vector>
     3 using namespace std; 
     4 const int N=100118;
     5 struct Side{
     6     int v,ne;
     7 }S[2*N];
     8 vector<int> ans;
     9 int n,k,is,m,sn;
    10 int head[N],size[N],book[N];
    11 void add(int u,int v)
    12 {
    13     S[sn].v=v;
    14     S[sn].ne=head[u];
    15     head[u]=sn++;
    16 }
    17 void fp(int u,int f)
    18 {
    19     for(int i=head[u];i!=-1;i=S[i].ne)
    20         if(S[i].v!=f&&!book[S[i].v])
    21         {
    22             book[S[i].v]=u;
    23             printf(" %d",S[i].v);
    24             fp(S[i].v,u);
    25         }
    26 }
    27 int dfs(int u,int f)
    28 {
    29     if(!is)
    30         return 0;
    31     size[u]=1;
    32     for(int i=head[u];i!=-1;i=S[i].ne)
    33     {
    34         if(S[i].v!=f&&!book[S[i].v])
    35             dfs(S[i].v,u);
    36         if(S[i].v!=f&&!book[S[i].v])//如果它的这个子节点没有作为划分的子树的根节点 
    37             size[u]+=size[S[i].v];//那么统计上它的大小 
    38     }
    39     if(size[u]>k)//如果它的子树大小大于k那么它分出一个大小k的子树后 
    40         return is=0;//剩下的会不足k个 
    41     if(size[u]==k)
    42     {
    43         ans.push_back(u);//保存作为划分的子树根节点的节点 
    44         book[u]=f;//并保存它的父节点,不然在输出时会PE 
    45     }
    46     return 1;
    47 }
    48 int main()
    49 {    
    50     int t,a,b;
    51     scanf("%d",&t);
    52     while(t--)
    53     {
    54         scanf("%d%d",&n,&k);
    55         ans.clear();
    56         for(int i=1;i<=n;i++)
    57             book[i]=0,head[i]=-1;
    58         sn=0;
    59         for(int i=0;i<n-1;i++)
    60         {
    61             scanf("%d%d",&a,&b);
    62             add(a,b),add(b,a);
    63         }
    64         is=1;
    65         if(dfs(1,-1))
    66         {
    67             printf("YES
    ");
    68             for(int i=0;i<ans.size();i++)
    69             {
    70                 printf("%d",ans[i]);
    71                 fp(ans[i],book[ans[i]]);
    72                 printf("
    ");
    73             }
    74         }
    75         else
    76             printf("NO
    ");
    77     }
    78     return 0;
    79 }
    多想一想
  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10515899.html
Copyright © 2011-2022 走看看