P1041 [NOIP2003 提高组] 传染病控制

题目描述

研究表明,这种传染病的传播具有两种很特殊的性质;

第一是它的传播途径是树型的,一个人 X 只可能被某个特定的人 Y 感染,只要 Y 不得病,或者是 XY 之间的传播途径被切断,则 X 就不会得病。

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

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

你的程序要针对给定的树,找出合适的切断顺序。

输入格式

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

输出格式

11 行,总共被感染的人数。

输入输出样例

输入 #1复制

7 6
1 2
1 3
2 4
2 5
3 6
3 7

输出 #1复制

3

说明/提示

对于 100%100% 的数据,1≤n≤300。

【题目来源】

NOIP 2003 提高组第四题

题解:

题目的意思是:

给你一颗树,每次划掉一条边避免被感染,感染源从1开始,先叶子结点扩散。

看了其他人的题解,总结一下思路:

我们可以逆向思维,就是求保护多少个人不被感染。

我们观察到每次我们只可能以1为根的树,每次每层断过掉一个子节点,这时就转变为这么才可以断掉子节点 到叶子节点的个数最多。

我们用 最短路算法求其每个节点 和它的子儿子。

因为父节点到子节点的路径是 dis[f] + 1 = dis[r] ;

struct node{int x, quan;node (int a, int b) : x(a), quan(b){}friend bool operator < (node a, node b){return a.quan > b.quan;}
};
/预处理第二部分
void solve(){priority_queue <node> que;for (int i = 0; i <= n; ++i) dis[i] = 999;dis[1] = 0;que.push(node(1, 0));while (!que.empty()){node temp = que.top();que.pop();int x = temp.x;int p = k[x].size();for (int j = 0; j < p; ++j){if (dis[k[x][j]] > dis[x]+1){dis[k[x][j]] = dis[x]+1;que.push(node(k[x][j], dis[k[x][j]]));}}}resolve(1, 0);
} //最短路算法进行预处理

在利用 resove(1,0)处理记录,第cet层的每个节点的个数。

//dfs核心函数
void resolve(int i, int cen){//cet为1节点 的第几层  // i为节点 的值b[cen][cnt[cen]] = i;// 第几层的位置  存放节点++cnt[cen];int p = k[i].size();for (int j = 0; j < p; ++j){ // k[i][j] 是i点 -> k[i][j]if (dis[k[i][j]] == dis[i]+1){//下一个点 的化resolve(k[i][j], cen+1);f[i].push_back(k[i][j]);//为了取出最近的一个点}}
} 

再用 dfs进行记录最大可以保护不被感染的个数

遍历每层它的最大保护的个数。

//标记部分
void reclean(int i){bol[i] = false;int p = f[i].size();for (int j = 0; j < p; ++j){reclean(f[i][j]);}
} //回溯部分
void dfs(int cen, int tot){// 1 0 maxx = max(maxx, tot); //最大 的那一层for (int i = 0; i < cnt[cen]; ++i){if (!bol[b[cen][i]]){ // 这个节点 有没有被访问过 int num = clean(b[cen][i]);tot += num;// 砍断 这个东西 dfs(cen+1, tot);reclean(b[cen][i]);tot -= num;}}
} 

总代码:

#include<cstdio>//要靠虑深度 深度+1才是它的儿子
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#define LL long long
using namespace std;
int n, p, t1, t2, b[305][305], cnt[305], maxx = 0, dis[305];
bool bol[305], vis[305];
vector <int> k[305], f[305];
struct node{int x, quan;node (int a, int b) : x(a), quan(b){}friend bool operator < (node a, node b){return a.quan > b.quan;}
};
int clean(int i){//相近的节点 在第i个节点开始 包括第i个节点下层还有多少个节点 bol[i] = true;int num = 1;int p = f[i].size();for (int j = 0; j < p; ++j){num += clean(f[i][j]);}return num;
} //标记部分
void reclean(int i){bol[i] = false;int p = f[i].size();for (int j = 0; j < p; ++j){reclean(f[i][j]);}
} //回溯部分
void dfs(int cen, int tot){// 1 0 maxx = max(maxx, tot); //最大 的那一层for (int i = 0; i < cnt[cen]; ++i){if (!bol[b[cen][i]]){ // 这个节点 有没有被访问过 int num = clean(b[cen][i]);tot += num;// 砍断 这个东西 dfs(cen+1, tot);reclean(b[cen][i]);tot -= num;}}
} //dfs核心函数
void resolve(int i, int cen){//cet为1节点 的第几层  // i为节点 的值b[cen][cnt[cen]] = i;// 第几层的位置  存放节点++cnt[cen];int p = k[i].size();for (int j = 0; j < p; ++j){ // k[i][j] 是i点 -> k[i][j]if (dis[k[i][j]] == dis[i]+1){//下一个点 的化resolve(k[i][j], cen+1);f[i].push_back(k[i][j]);//为了取出最近的一个点}}
} 
//预处理第二部分
void solve(){priority_queue <node> que;for (int i = 0; i <= n; ++i) dis[i] = 999;dis[1] = 0;que.push(node(1, 0));while (!que.empty()){node temp = que.top();que.pop();int x = temp.x;int p = k[x].size();for (int j = 0; j < p; ++j){if (dis[k[x][j]] > dis[x]+1){dis[k[x][j]] = dis[x]+1;que.push(node(k[x][j], dis[k[x][j]]));}}}resolve(1, 0);
} //最短路算法进行预处理
//实际上以节点0开始进行拓扑排序效率更高
int main(){scanf("%d %d", &n, &p);for (int i = 0; i < p; ++i){scanf("%d %d", &t1, &t2);k[t1].push_back(t2);k[t2].push_back(t1);}solve();dfs(1, 0);printf("%d", n-maxx);
}

时间复杂度:O(n*n)因为遍历n个节点 ,dfs遍历n次 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/753502.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年56套包含java,ssm,springboot的平台设计与实现项目系统开发资源(可运行源代码+设计文档)分享【万字长文收藏耐心看】

序号项目名称项目链接1某品零食交易平台设计与实现|基于springboot MysqlJava的某品交易平台设计与实现(源码数据库文档PPT)https://xiaoxiao.blog.csdn.net/article/details/136463403?spm1001.2014.3001.55022毕业生信息招聘平台|基于springboot MysqlJava的毕业生信息招聘平…

LLM 面试知识点——模型基础知识

1、主流架构 目前LLM(Large Language Model)主流结构包括三种范式,分别为Encoder-Decoder、Causal Decoder、Prefix Decode。对应的网络整体结构和Attention掩码如下图。 、 各自特点、优缺点如下: 1)Encoder-Decoder 结构特点:输入双向注意力,输出单向注意力。 代表…

Tomcat:Session ID保持会话

目录 前言 ​一、部署环境 二、部署nginx反向代理服务器 三、部署tomcat服务器1 四、部署tomcat服务器2 五、客户端测试&#xff08;Session ID不断变动&#xff09; 六、配置Session ID会话保持 七、客户端测试&#xff08;Session ID保持&#xff09; 前言 此次实验…

nginx location块配置

nginx可以通过配置文件中的location指令来定义不同的请求匹配规则和处理逻辑&#xff0c;也就是描述不同请求资源在服务器的位置或者配置代理转发路径。 location块通常在server块中&#xff0c;一个server块可以包含多个location块。 server {location {}location {} }语法规…

客户端渲染与服务端渲染(1)

客户端渲染即普通的 React 项目渲染方式。 客户端渲染流程&#xff1a; 浏览器发送请求 服务器返回 HTML 浏览器发送 bundle.js 请求 服务器返回 bundle.js 浏览器执行 bundle.js 中的 React 代码 CSR 带来的问题&#xff1a; 首屏加载时间过长 SEO 不友好 因为时间在往返的几…

python内置函数 M

python内置函数 M Python 解释器内置了很多函数和类型&#xff0c;任何时候都能使用。 M 名称描述map返回一个迭代器&#xff0c;其中包含函数应用于每个元素的结果。max返回给定可迭代对象&#xff08;如列表、元组、字符串等&#xff09;中的最大元素。memoryview返回由给…

C语言自定义库

编写 xx.c 和xx.h文件\将源代码编译为目标文件 gcc -c add.c sub.c 执行完毕后会生产add.o和sub.o文件静态库创建使用ar命令&#xff1b; ar -r libmymath.a add.o sub.o将库和main.c文件一起编译 gcc -o main main.c -lmymath -L./ 注意 上述书写格式不要错乱 -L 是指定文件路…

鸿蒙-项目创建及了解

目录 项目创建 1.App普通项目创建 2.元服务创建 项目结构 .hvigor .idea AppScope entry EntryAbility.ts pages resources module.json5 ohosTest hvigorfile.ts build-profile.json5 oh_modules build-profile.json5 hvigorfile.ts 项目运行 项目创建 F…

uniapp的描述的展开与收缩,超过三行有省略号才显示

html代码&#xff1a; <view class"desc_box"><view id"desc" class"desc" :class"open ? open : three">{{ data.desc }}</view><view class"expand theme-color" click"unfold" v-if&qu…

单模场哈密顿量推导

满足麦克斯韦方程和边界条件的单模场又下式&#xff08;1&#xff09;&#xff0c;&#xff08;2&#xff09;给出 --------&#xff08;1&#xff09; ---------&#xff08;2&#xff09; , 单模场的经典场能或者哈密顿量又下式给出&#xff1a; &#xff08;3&#xff09…

JUC并发编程(四)

1、同步模式保护性暂停 用一个线程等待另一个线程的执行结果 有一个结果需要从一个线程传递到另一个线程&#xff0c;让他们关联同一个中间类。如果有结果不断从一个线程到另一个线程那么可以使用消息队列&#xff08;见生产者/消费者&#xff09;。JDK 中&#xff0c;join 的…

WebAssembly探索篇(三)emcc和cmake编译opencv案例

文章目录 开发环境安装opencv环境 实践出真知完整项目效果图 踩坑fatal error: opencv2/opencv.hpp file not found增加软链ln&#xff08;无效&#xff09;改用自行安装opencv&#xff0c;再显示指定lib路径 emcc命令行运行方式 最近因为项目原因&#xff0c;研究了一下WebAss…

Anaconda概述

Anaconda是一个开源的Python发行版本&#xff0c;它整合了Python解释器、Conda包和环境管理器以及众多预装的科学计算库和工具包。这使得用户能够方便地使用和管理多个Python版本&#xff0c;并在不同的环境中调用不同的数据包。 Conda是Anaconda中的一个关键组件&#xff0c;…

C语言例:表达式 45-35+1^2 的值

代码如下&#xff1a; #include<stdio.h> int main(void) {int a;a 4&5-3&&51^2;printf("4&5-3&&51^2 %d\n",a);return 0; } 结果如下&#xff1a;

maven一点通

1.maven简介 Maven是一个基于Java的工程构建工具&#xff0c;用于管理和构建项目的依赖关系。它提供了一种标准的项目结构和一组约定&#xff0c;使得项目的开发、构建、部署和文档化更加容易和可靠。 Maven的主要功能包括&#xff1a; 依赖管理&#xff1a;Maven可以自动下载…

课设系统篇

《古代六扇门人员管理系统》 数据库 sixdoor 编码 utf8mb4 视图 查询官员等级 存储过程 CREATE DEFINERrootlocalhost PROCEDURE levelname(IN g_name VARCHAR(20)) BEGINSELECT name,level FROM servingofficials INNER JOIN jobtitle onservingofficials.role jobtitl…

Android性能自测

目录 一、应用启动耗时自测 二、帧率查看 三、Top命令查看系统资源占用 3.1 第一行&#xff1a;任务(进程) 3.2 第二行&#xff1a;mem状态 3.3 第三行&#xff1a;swap交换分区 3.4 第四行&#xff1a;cpu状态 3.5 第五行&#xff1a;标题 四、抓取trace.html文件分析…

【CSP考点回顾】C++标准库加速输入输出

C标准库加速输入输出 ios_base::sync_with_stdio(false);&#xff1a;取消C标准库&#xff08;iostream&#xff09;与C标准库&#xff08;stdio&#xff09;之间的同步。默认情况下&#xff0c;为了保证C的cin、cout与C的stdin、stdout能够互相交换数据&#xff0c;它们之间会…

基于tcp协议的网络通信(基础echo版.多进程版,多线程版,线程池版),telnet命令

目录 基础版 思路 辅助函数 服务端 代码 运行情况 -- telnet ip 端口号 传输的数据为什么没有转换格式 客户端 思路 代码 多进程版 引入 问题 解决 注意点 服务端 代码 运行情况 进程池版(简单介绍) 多线程版 引入 问题解决 注意点 服务端 代码 …

嵌入式Linux 内核的内存管理方法

内存管理的主要工作就是对物理内存进行组织,然后对物理内存的分配和回收。但是Linux引入了虚拟地址的概念。 虚拟地址的作用 如果用户进程直接操作物理地址会有以下的坏处: 1、 用户进程可以直接操作内核对应的内存,破坏内核运行。 2、 用户进程也会破坏其他进程的运行 …