NOIP2003 传染病防治

描述

研究表明,这种传染病的传播具有两种很特殊的性质;
第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y不
得病,或者是XY之间的传播途径被切断,则X就不会得病。

第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一
代患者,而不会再传播给下一代。

这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群
的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。你的程序要针对给定的树,找出合适的切断顺序。

格式

输入格式

输入格式的第一行是两个整数n(1≤n≤300)和p。接下来p行,每一行有两个整数i
和j,表示节点i和j间有边相连(意即,第i人和第j人之间有传播途径相连)。其中节点
1是已经被感染的患者。

输出格式

只有一行,输出总共被感染的人数。

改了好久才AC,代码有点乱(很值得好好琢磨的一道题)

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstring>
 4 using namespace std;
 5 struct edge{
 6   int f,t;
 7 };
 8 const int maxn=300+10;
 9 int n,p,node[maxn],flag[maxn],ans=maxn,cs;
10 vector<edge> b[maxn];
11 vector<int> GG[maxn];
12 vector<int> G[maxn];
13 int calcsize(int x){
14   node[x]=1;
15   if(G[x].size()==0) return node[x];
16   for(int i=0;i<G[x].size();i++) node[x]+=calcsize(G[x][i]);
17   return node[x];
18 }
19 void dfs1(int n,int f){
20   if(G[f].size()==0){
21     return;
22   }
23   for(int i=0;i<G[f].size();i++){
24     b[n].push_back((edge){f,G[f][i]});
25     dfs1(n+1,G[f][i]);
26   }
27 }
28 void vis(int x){
29     flag[x]=1;
30     for(int i=0;i<G[x].size();i++) vis(G[x][i]);
31 }
32 void disvis(int x){
33     flag[x]=0;
34     for(int i=0;i<G[x].size();i++) disvis(G[x][i]);
35 }
36 void dfs(int n,int now){
37     ans=min(ans,now);
38     if(n>cs){
39         return;
40     }
41     for(int i=0;i<b[n].size();i++){
42         edge &e=b[n][i];
43         if(!flag[e.f]){
44             vis(e.t);dfs(n+1,now-node[e.t]);
45             disvis(e.t);
46         }
47     }
48
49 }
50 void bulid(int u,int fa){
51     int d=GG[u].size();
52     for(int i=0;i<d;i++){
53         int v=GG[u][i];
54         if(v!=fa){
55             G[u].push_back(v);
56             bulid(v,u);
57         }
58     }
59 }
60 int main()
61 {
62   int i,j;
63   cin>>n>>p;
64   for(int k=0;k<p;k++){
65     cin>>i>>j;GG[i].push_back(j);GG[j].push_back(i);
66   }
67   memset(flag,0,sizeof(flag));
68   bulid(1,-1);calcsize(1);dfs1(1,1);
69   for(int i=1;i<=maxn;i++){
70     if(b[i].size()==0){
71         cs=i-1;break;
72     }
73   }dfs(1,n);cout<<ans;
74   return 0;
75 }
时间: 2024-08-15 22:48:43

NOIP2003 传染病防治的相关文章

[NOIP2003] 传染病控制题解

问题 F: [NOIP2003] 传染病控制 时间限制: 1 Sec  内存限制: 128 MB 题目描述 [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府 决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群.于是,蓬莱国 的疾病控制中心决定采取切断传播途径的方法控制疾病传播.经过 WHO (世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径

noip2003提高组题解

这一年的前三题虽然难度不高,但是第二题极为繁琐,想在考场上用较短的时间拿到第二题的分数难上加难.所以必须要调整策略,争取拿其他三题的分数.第四题是比较普通的搜索题,分数比较好拿,但是很容易想成树形DP,就只能拿30~50分. ? 第一题:神经网络 模拟 有几个注意点: 输入层(即第一层)的结点的U(阈值)是没有用的: 题目说输出「最后状态非零的输出层神经元状态」,但实际上输出的是状态大于0的值. 由于没有注意到神经元只有在兴奋状态时才会向下传送信号,所以WA了1次. ? 第二题:侦探推理 模拟+

vijos 1106 &amp; NOIP2003 提高组 侦探推理 题解

[原题] P1106侦探推理 Accepted 标签:[显示标签] 描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯.接着,明明逐个询问每一个同学,被询问者可能会说: 证词中出现的其他话,都不列入逻辑推理的内容. 明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真. 现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,

cogs 106. [NOIP2003] 加分二叉树(区间DP)

106. [NOIP2003] 加分二叉树 ★☆   输入文件:jfecs.in   输出文件:jfecs.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 设 一个 n 个节点的二叉树 tree 的中序遍历为( l,2,3,…,n ),其中数字 1,2,3,…,n 为节点编号.每个节点都有一个分数(均为正整数),记第 j 个节点的分数为 di , tree 及它的每个子树都有一个加分,任一棵子树 subtree (也包含 tree 本身)的加分计算方法如下: su

cogs 983. [NOIP2003] 数字游戏

983. [NOIP2003] 数字游戏 ★☆   输入文件:numgame.in   输出文件:numgame.out   简单对比时间限制:1 s   内存限制:128 MB 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k.游戏的要求是使你所得的k最大或者

Catalan数 &amp;&amp; 【NOIP2003】出栈序列统计

令h(1)=1, h(0)=1,catalan数满足递归式: h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)h(0) (n>=2) =C(2n, n)/(n+1) =h(n-1)*2(2n-1)/(n+1) 具体推导请百度,这里只需记得推导公式为h(n)=h(n-1)*2(2n-1)/(n+1)即可. 我们来说说这个的应用吧,从catalan数的定义递归定义可以看出,它是由自己 本身的一部分和n减去一部分 的和得到的,也就是说,有n个物品,1个物品进行操作1,n-

[NOIP2003]栈 题解(卡特兰数)

[NOIP2003]栈 Description 宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n(图示为1到3的情况),栈A的深度大于n. 现在可以进行两种操作: 1.将一个数,从操作数序列的头端移到栈的头端(对应数据结构栈的push操作) 2.将一个数,从栈的头端移到输出序列的尾端(对应数据结构栈的pop操作) 使用这两种操作,由一个操作数序列就可以得到一系列的输出序列; 你的程序将对给定的n,计算并输出由操作数序列1,2,-,n经过操作可能得到的输出序列的总数. Solution

【noip2003】 麦森数

题目描述 形如2P-1的素数称为麦森数,这时P一定也是个素数.但反过来不一定,即如果P是个素数,2P-1不一定也是素数.到1998年底,人们已找到了37个麦森数.最大的一个是P=3021377,它有909526位.麦森数有许多重要应用,它与完全数密切相关. 任务:从文件中输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示) 输入 文件中只包含一个整数P(1000<P<3100000) 输出 第一行:十进制高精度数2P-1的位数. 第2

[NOIP2003] 提高组 洛谷P1039 侦探推理

题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情况下),明明的任务就是找出这个罪犯.接着,明明逐个询问每一个同学,被询问者可能会说: 证词中出现的其他话,都不列入逻辑推理的内容. 明明所知道的是,他的同学中有N个人始终说假话,其余的人始终说真. 现在,明明需要你帮助他从他同学的话中推断出谁是真正的凶手,请记住,凶手只有一个! 输入输出格式 输入格式: 输入由若干行组