zoukankan      html  css  js  c++  java
  • 【EOJ3654】管理孩子(贪心,二分)

    题意:有一棵n个点的树,其中有k个是关键点,将树分割成若干部分,每部分至少包含一个关键点,求最大分割大小的最小值

    思路:

    最后特判一下f[1]的值

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<ctime>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second 
     19 #define MP make_pair
     20 #define mem0(a) memset(a,0,sizeof(a))
     21 #define N  210000
     22 #define M  130
     23 #define MOD 1000000007
     24 #define eps 1e-8 
     25 #define pi acos(-1)
     26 #define oo 1000000000
     27 
     28 int flag[N],f[N],a[N],n,mx;
     29 vector<int>c[N];
     30 
     31 void dfs(int u)
     32 {
     33     flag[u]=1;
     34     if(a[u]) 
     35     {
     36         int t=0;
     37         for(int i=0;i<=(int)c[u].size()-1;i++)
     38         {
     39             int v=c[u][i];
     40             if(!flag[v])
     41             {
     42                 dfs(v);
     43                 if(f[v]<0) t-=f[v];
     44             }
     45         }
     46         f[u]=t+1;
     47     }
     48      else
     49      {
     50          int t=0,s=oo;
     51          for(int i=0;i<=(int)c[u].size()-1;i++)
     52          {
     53              int v=c[u][i];
     54              if(!flag[v])
     55              {
     56                  dfs(v);
     57                  if(f[v]<0) t-=f[v];
     58                  else s=min(s,f[v]);
     59             }
     60         }
     61         if(mx-s>=t+1) f[u]=s+t+1;
     62          else f[u]=-t-1; 
     63      }
     64 }
     65 
     66 int isok(int m)
     67 {
     68     mem0(flag);
     69     mem0(f);
     70     mx=m;
     71     dfs(1);
     72     int flag=1;
     73     if(f[1]<0) return 0;
     74     for(int i=1;i<=n;i++) 
     75      if(abs(f[i])>m) return 0;
     76     return 1;
     77 }
     78 
     79 int main()
     80 {
     81     int k;
     82     scanf("%d%d",&n,&k);
     83     for(int i=1;i<=n-1;i++)
     84     {
     85         int x,y;
     86         scanf("%d%d",&x,&y);
     87         c[x].push_back(y);
     88         c[y].push_back(x);
     89     }
     90     for(int i=1;i<=k;i++)
     91     {
     92         int x;
     93         scanf("%d",&x);
     94         a[x]=1;
     95     }
     96     int l=1,r=n,last=n;
     97     while(l<=r)
     98     {
     99         int mid=(l+r)>>1;
    100         if(isok(mid)){last=mid; r=mid-1;}
    101          else l=mid+1;
    102     }
    103     printf("%d
    ",last);    
    104     return 0;         
    105 }
  • 相关阅读:
    浅谈MSSQL2012中的列存储索引(columnstore indexes)
    《高性能SQL调优精要与案例解析》新书样章
    关系库执行计划中三种最常用连接方式的伪码实现
    python基础-字符串
    python基础-文件和目录
    python基础-列表
    python基础-对象
    python基础-入门
    python算法-二叉树广度优先遍历
    Python算法-二叉树深度优先遍历
  • 原文地址:https://www.cnblogs.com/myx12345/p/10097092.html
Copyright © 2011-2022 走看看