luogu_1041【题解】搜索 传染病控制

题面:https://www.luogu.org/problemnew/show/P1041

大意:太难解释了,自行领会吧(滑稽

看到n比较小,决定用暴力搜索(因为标签就是搜索

大部分注释都在代码中,自行理解。

借鉴抄袭大佬思路:https://www.luogu.org/blog/beautiful-Andy-park/solution-p1041

代码如下。

#include<bits/stdc++.h>
#define rr register
#define sc(x) scanf("%d",&x)
using namespace std;
const int maxn=400;
int n,p,cou[maxn];
struct node{
    int fa,ch[maxn],num;//num儿子数量
    #define fa(x) point[x].fa
    #define num(x) point[x].num
}point[maxn];
inline void init(){
    for(rr int i=1;i<=n;i++)
        num(i)=0,cou[i]=1;
    for(rr int i=1;i<=p;i++){
        int x,y;
        sc(x),sc(y);
        if(x>y) swap(x,y);
        fa(y)=x;
        num(x)++;
        point[x].ch[num(x)]=y;
    }
}
int dep[maxn][maxn],maxx=0;
inline void getdeep(int b,int now){
    maxx=max(maxx,now);
    for(rr int i=1;i<=num(b);i++){
        dep[now][0]++;
        dep[now][dep[now][0]]=point[b].ch[i];
        getdeep(point[b].ch[i],now+1);
    }
}
int vis[maxn];
//数子树的元素
inline int count(int b){
    for(rr int i=1;i<=num(b);i++)
        cou[b]+=count(point[b].ch[i]);
    return cou[b];
}
//切子树
inline void cut(int b,int tag){//tag=1 标记 tag=0 没有
    for(rr int i=1;i<=num(b);i++){
        vis[point[b].ch[i]]=tag;
        cut(point[b].ch[i],tag);
    }
}
int ans=1100;
inline void dfs(int now,int cnt){
    if(now==maxx){
        ans=min(ans,cnt);
        return;
    }
    int tg=0;//这一层的数
    for(rr int i=1;i<=dep[now][0];i++){
        if(vis[dep[now][i]]>0){
            tg++;
            continue;
        }
        vis[dep[now][i]]=1;
        cut(dep[now][i],1);
        dfs(now+1,cnt-cou[dep[now][i]]);
        vis[dep[now][i]]=0;
        cut(dep[now][i],0);
    }
    if(tg==dep[now][0]) ans=min(ans,cnt);
}
int main()
{
    sc(n),sc(p);
    init();
    getdeep(1,2);
    count(1);
    dfs(2,n);
    cout<<ans<<endl;
    // system("pause");
    return 0;
}

 

posted @ 2019-07-04 10:02  ChrisKKK  阅读(181)  评论(0编辑  收藏  举报