传染病控制

在这里插入图片描述
由于题给数据量较小,所以暴力搜索很容易过

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<stack>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int num[500];//存储节点数
int deeper[500][500];//存储深度及编号
int vis[500];
int deepers=0,n,m,ans=1000;
vector<int>E[500];//存边

struct edge
{
    int from,to,val;
}h;

int Count(int tree)//统计节点数
{
    int sz=E[tree].size();
    for(int i=0;i<sz;i++)
    {
        num[tree]+=Count(E[tree][i]);
    }
    return num[tree];
}

void Deep(int tree,int deep)//上一层的根节点,这一层的深度
{
    deepers=max(deepers,deep);
    int sz=E[tree].size();
    for(int i=0;i<sz;i++)
    {
        deeper[deep][0]++;
        deeper[deep][deeper[deep][0]]=E[tree][i];
        Deep(E[tree][i],deep+1);
    }
    return ;
}

void work(int tree,int trag)//为了避免同一深度搜索时重复
{
    int sz=E[tree].size();
    for(int i=0;i<sz;i++)
    {
        vis[E[tree][i]]=trag;
        work(E[tree][i],trag);
    }
    return ;
}

void dfs(int deep,int cnt)//感染数目
{
    if(deep==deepers)
    {
        ans=min(ans,cnt);
        return;
    }
    int flag=0;
    for(int i=0;i<deeper[deep][0];i++)
    {
        if(vis[deeper[deep][i+1]])
        {
            flag++;
            continue;
        }
        vis[deeper[deep][i+1]]=1;//标记根节点,并标记相应所有子节点
        work(deeper[deep][i+1],1);
        dfs(deep+1,cnt-num[deeper[deep][i+1]]);
        vis[deeper[deep][i+1]]=0;
        work(deeper[deep][i+1],0);

    }
    if(flag==deeper[deep][0])//当同一深度都被标记则感染完毕更新感染数目
        ans=min(ans,cnt);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int u,v;
        cin>>u>>v;
        E[min(u,v)].push_back(max(u,v));
    }
    for(int i=1;i<=n;i++) num[i]=1;//初始化数目
    Count(1);
    Deep(1,2);
    dfs(2,n);
    cout<<ans<<endl;

}