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

这道题的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=;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=(sum<<)+(sum<<)+ch-'',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<<];
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]=;
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+),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=;i<floor[deep+].size();i++)
if(did[f[floor[deep+][i]]])
did[floor[deep+][i]]=;
for(int i=;i<floor[deep+].size();i++)
if(did[floor[deep+][i]]==){
did[floor[deep+][i]]=;
Dfs(deep+,ans+size[floor[deep+][i]]);
did[floor[deep+][i]]=;
}
for(int i=;i<floor[deep+].size();i++)
if(did[f[floor[deep+][i]]])
did[floor[deep+][i]]=;
}
}
namespace mid{
int n,m;
inline void Init(){
using pre :: read;
using tree :: add;
read(n),read(m);
for(int i=,a,b;i<=m;i++)
read(a),read(b),add(a,b),add(b,a);
tree :: dfs(,,);
}
inline void Work(){
using namespace tree;
for(int i=Deep_Max;i>;i--){
std::sort(floor[i].begin(),floor[i].end(),comp);
Max[i]=Max[i+]+size[floor[i][]];
}
Dfs(,);
printf("%d",n-pre::ans);
}
}
int main(){
freopen("epidemic.in","r",stdin);
freopen("epidemic.out","w",stdout);
mid :: Init();
mid :: Work();
return ;
}
05-27 00:15