洛谷 P1041 传染病控制 题解

这道题是一个错题,但是我还是做了。

一开始我想的是一个贪心的做法,但是如果树含有一条很长的链就会hack掉这种做法,而数据范围并不大,所以就老老实实地写搜索。

大体上是先搜索一遍整棵树,处理处每个点的父亲节点编号,子树大小和所在深度。

然后需要把相同深度的点归到一起,因为对于每次搜索,可选择的都是同一层的点(本来是边,可以转换成点)。

然后就是根据题意搜索:每次在同层的点中选一个切断。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 610
#define int long long
#define rep(i,s,e) for(register int i=s;i<=e;++i)
#define dwn(i,s,e) for(register int i=s;i>=e;--i)
using namespace std;
inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    return f*x;
}
inline void write(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
vector<int> sd[maxn];
int n,p,cnt,ans,maxdep;
int head[maxn];
int fa[maxn],siz[maxn],deep[maxn],tag[maxn];
struct node
{
    int v,nex;
}edge[maxn];
inline void add(int x,int y)
{
    edge[++cnt].v=y;
    edge[cnt].nex=head[x];
    head[x]=cnt;
}
void pre_dfs(int now,int from,int dep)
{
    fa[now]=from;
    siz[now]=1;
    deep[now]=dep;
    maxdep=max(maxdep,dep);
    for(int i=head[now];i;i=edge[i].nex)
    {
        int to=edge[i].v;
        if(to==from) continue;
        pre_dfs(to,now,dep+1);
        siz[now]+=siz[to];
    }
}
void dfs(int dep,int f)
{
    if(dep==maxdep+1)
    {
        ans=min(ans,f);
        return;
    }
    for(int i=0;i<sd[dep].size();++i)
    {
        if(tag[fa[sd[dep][i]]]==1) tag[sd[dep][i]]=1;
        else tag[sd[dep][i]]=0;
    }
    bool flag=0;
    for(int i=0;i<sd[dep].size();++i)
    {
        if(tag[sd[dep][i]]==0) flag=1;
    }
    if(flag==0)
    {
        ans=min(ans,f);
        return;
    }
    for(int i=0;i<sd[dep].size();++i)
    {
        if(tag[sd[dep][i]]==1) continue;
        tag[sd[dep][i]]=1;
        dfs(dep+1,f-siz[sd[dep][i]]);
        tag[sd[dep][i]]=0;
    }
}
signed main()
{
    n=read();p=read();
    ans=n;
    rep(i,1,p)
    {
        int x=read(),y=read();
        add(x,y);
        add(y,x);
    }
    pre_dfs(1,0,1);
    rep(i,1,n) sd[deep[i]].push_back(i);
    dfs(2,n);
    write(ans);
    return 0;
}

 

posted @ 2020-09-10 17:09  handsome_zyc  阅读(150)  评论(0编辑  收藏  举报