Luogu1041 NOIP2003T4 传染病控制 搜索

题目传送门:https://www.luogu.org/problemnew/show/P1041

题意:一棵有$N$个节点的有根树的根节点($1$号点)出现了传染病病毒,每一次你可以切断树上的一条边,然后病毒就会沿着边向叶子节点拓展一层,感染新一层节点,求最少有多少个节点被感染(1号节点最开始被感染)。$N \leq 300$


 

$15$年前的搜索题就是不一样,暴搜加个最优化剪枝就能过$qwq$

根据贪心可以知道,每一次切断的一条边必定联系最新被感染的节点和它的儿子,所以每一次只需要枚举下面的哪个儿子不会被感染就可以了,复杂度$O($玄学$)$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 inline int read(){
 4     int a = 0;
 5     char c = getchar();
 6     while(!isdigit(c))    c = getchar();
 7     while(isdigit(c))    a = (a << 3) + (a << 1) + (c ^ 48) , c = getchar();
 8     return a;
 9 }
10 inline int min(int a , int b){
11     return a < b ? a : b;
12 }
13 vector < int > Ed[301];
14 queue < int > q;
15 int minN = 0x3f3f3f3f;
16 bool vis[301];
17 void choose(int , queue < int >);
18 void create(int num , queue < int > q){
19     queue < int > q1;
20     register int sum = 0;
21     while(!q.empty()){
22         int t = q.front();
23         q.pop();
24         num++;
25         for(register int i = 0 ; i < Ed[t].size() ; i++)
26             if(!vis[Ed[t][i]]){
27                 q1.push(Ed[t][i]);
28                 if(num + ++sum > minN)    return;
29             }
30     }
31     if(num + sum > minN)    return;
32     if(sum == 0){
33         minN = min(minN , num);
34         return;
35     }
36     choose(num , q1);
37 }
38 int main(){
39     register int n = read() , p = read();
40     for(register int i = 0 ; i - p ; i++){
41         int a = read() , b = read();
42         Ed[a].push_back(b);
43         Ed[b].push_back(a);
44     }
45     q.push(1);
46     vis[1] = 1;
47     create(0 , q);
48     printf("%d" , minN);
49     return 0;
50 }
51 void choose(int num , queue < int > q){
52     register int first = q.front();
53     do{
54         vis[q.front()] = 1;
55         q.push(q.front());
56         q.pop();
57     }while(q.front() - first);
58     do{
59         register int t = q.front();
60         q.pop();
61         create(num , q);
62         q.push(t);
63     }while(q.front() - first);
64     while(!q.empty()){
65         vis[q.front()] = 0;
66         q.pop();
67     }
68 }

 

猜你喜欢

转载自www.cnblogs.com/Itst/p/9751925.html
今日推荐