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; }