【NOIP2003提高组T4】传染病控制-DFS剪枝
测试地址:传染病控制
做法:按层DFS。每一次在当前层的备选点中枚举一个点,砍掉它的子树,然后继续搜索,找最小值即可。
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define inf 2000000000
using namespace std;
int n,p,tot=0,first[310]={0},f[310]={0};
struct edge {int v,next;} e[610];
vector<int> G[310];
void insert(int a,int b)
{
e[++tot].v=b;
e[tot].next=first[a];
first[a]=tot;
}
void DFS(int v,int f)
{
for(int i=first[v];i;i=e[i].next)
if (e[i].v!=f)
{
G[v].push_back(e[i].v);
DFS(e[i].v,v);
}
}
int dfs(const vector<int> &state) //参数这样定义就会变快,我不知道为什么,望大神解释解释
{
int len=state.size();
if (!len) return 0;
int ans=inf; //ans记录这层以下的最小答案
vector<int> next;
for(int i=0;i<len;i++)
{
next.clear();
for(int j=0;j<len;j++)
if (j!=i)
{
int v=state[j];
for(unsigned int k=0;k<G[v].size();k++)
next.push_back(G[v][k]);
}
ans=min(ans,dfs(next));
}
return ans+len-1;
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=p;i++)
{
int a,b;
scanf("%d%d",&a,&b);
insert(a,b);insert(b,a);
}
DFS(1,0);
vector<int> a;
for(unsigned int i=0;i<G[1].size();i++)
a.push_back(G[1][i]);
printf("%d",dfs(a)+1);
return 0;
}