P1041 传染病控制——暴力遍历所有相同深度的节点

P1041 传染病控制

说实话这种暴力我还是头一次见,每次病毒都会往下传染一层;

数据范围小,我们可以直接枚举当前层保护谁就好了;

用vector 记录相同层数的节点;维护已经断了的点;

如果超出最底层或者都已经被保护就更新答案;

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1010;
vector<int> v[maxn];
int pre[maxn],last[maxn],other[maxn],l;

void add(int x,int y)
{
    l++;
    pre[l]=last[x];
    last[x]=l;
    other[l]=y;
}

int n,m;

int siz[maxn],dep[maxn];

int father[maxn];

int madep;
void dfs1(int x,int fa)
{
    siz[x]=1;
    dep[x]=dep[fa]+1;
    father[x]=fa;
    madep=max(madep,dep[x]);
    for(int p=last[x];p;p=pre[p])
    {
        int v=other[p];
        if(v==fa) continue;
        dfs1(v,x);
        siz[x]+=siz[v];
    }
}

int vis[maxn];

int ans;

void dfs(int x,int sum)
{
    if(x==madep+1)
    {
        ans=min(ans,sum);
        return ;
    }
    bool flag=0;
    for(int i=0;i<v[x].size();i++)
    {
        if(vis[father[v[x][i]]])//chosen not ill
        {
            vis[v[x][i]]=1;
        }
        else {
        vis[v[x][i]]=0;
        flag=1;
        }
    }
    if(!flag)
    {
        ans=min(ans,sum);
        return ;
    }
    
    for(int i=0;i<v[x].size();i++)
    {
        int u=v[x][i];
        if(vis[u]) continue;
        vis[u]=1;
        dfs(x+1,sum-siz[u]);
        vis[u]=0;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs1(1,0);
    for(int i=1;i<=n;i++)
    {
        v[dep[i]].push_back(i);
    }
    ans=n;
    dfs(2,n);
    printf("%d",ans);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/WHFF521/p/11746620.html
今日推荐