[NOIP2003] 传染病控制 搜索+剪枝

Posted TS_Hugh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NOIP2003] 传染病控制 搜索+剪枝相关的知识,希望对你有一定的参考价值。

搜索的最广泛应用优化——剪枝

这道题的dp和贪心都是无正确性的,所以,搜~~~~~~~

搜的时候你发现不剪枝极容易被卡掉(然而良心NOIP没有这么做,不剪枝仍然飞快),所以我们需要一些玄学的剪枝最常见的有俩:I.我们一层一层累加被感染人群若当前被感染人群已经大于已知解那么就舍去。 II.之后的每一层如果都取最大仍不如已知解优则舍去。

玄学.........

#include <cstdio>
#include <vector>
#include <algorithm>
#define MAXN 310
namespace pre{
  inline void read(int &sum){
    register char ch=getchar();
    for(sum=0;ch<0||ch>9;ch=getchar());
    for(;ch>=0&&ch<=9;sum=(sum<<1)+(sum<<3)+ch-0,ch=getchar());
  }
  inline int Max(int x,int y){
    return x>y?x:y;
  }
  int ans;
}
namespace tree{
  struct tree{
    int to,next;
  }c[MAXN<<1];
  int head[MAXN],t,size[MAXN],f[MAXN],Deep_Max,Max[MAXN];
  bool did[MAXN];
  std::vector<int> floor[MAXN];
  inline int comp(int x,int y){
    return size[x]>size[y];
  }
  inline void add(int x,int y){
    c[++t].to=y;
    c[t].next=head[x];
    head[x]=t;
  }
  inline void dfs(int x,int fa,int deep){
    Deep_Max=pre::Max(deep,Deep_Max);
    size[x]=1;
    f[x]=fa;
    floor[deep].push_back(x);
    for(int i=head[x];i;i=c[i].next)
      if(c[i].to!=fa)
        dfs(c[i].to,x,deep+1),size[x]+=size[c[i].to];
  }
  inline void Dfs(int deep,int ans){
    //if(ans+Max[deep+1]<=pre::ans)return;
    pre::ans=pre::Max(ans,pre::ans);
    if(deep==Deep_Max)return;
    for(int i=0;i<floor[deep+1].size();i++)
      if(did[f[floor[deep+1][i]]])
        did[floor[deep+1][i]]=1;
    for(int i=0;i<floor[deep+1].size();i++)
      if(did[floor[deep+1][i]]==0){
        did[floor[deep+1][i]]=1;
        Dfs(deep+1,ans+size[floor[deep+1][i]]);
        did[floor[deep+1][i]]=0;
      }
    for(int i=0;i<floor[deep+1].size();i++)
      if(did[f[floor[deep+1][i]]])
        did[floor[deep+1][i]]=0;
  }
}
namespace mid{
  int n,m;
  inline void Init(){
    using pre :: read;
    using tree :: add;
    read(n),read(m);
    for(int i=1,a,b;i<=m;i++)
      read(a),read(b),add(a,b),add(b,a);
    tree :: dfs(1,0,1);
  }
  inline void Work(){
    using namespace tree;
    for(int i=Deep_Max;i>1;i--){
      std::sort(floor[i].begin(),floor[i].end(),comp);
      Max[i]=Max[i+1]+size[floor[i][0]];
    }
    Dfs(1,0);
    printf("%d",n-pre::ans);
  }
}
int main(){
  freopen("epidemic.in","r",stdin);
  freopen("epidemic.out","w",stdout);
  mid :: Init();
  mid :: Work();
  return 0;
}

 

以上是关于[NOIP2003] 传染病控制 搜索+剪枝的主要内容,如果未能解决你的问题,请参考以下文章

noip 2003 传染病控制(历史遗留问题2333)

[NOIP2003] 传染病控制题解

NOIP2003传染病控制

P1041 [2003NOIP提高组]传染病控制

[NOIP2003] 提高组 洛谷P1041 传染病控制

luogu cogs . [NOIP2003] 传染病控制 WA(1/2)