2012NOIP普及组真题 4. 文化之旅

线上OJ:

一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid=1960

相似题目:

本题和 2017年 NOIP J 组第3题 棋盘 类似。

核心思想:

由于本题的数据范围 n ≤ 100,非常小,所以可以采用 深搜 dfs 进行。同时,本题实际是求最短路,因此可用最短路的方法进行。由于 n 最大为100,所以即使采用 floyd 三重循环也只有 O ( 1 0 6 ) O(10^6) O(106)

题解代码:
解法一、深搜

1、从 起点国 开始,dfs每一个国家到起点国家的最短距离。
2、向下dfs时的判断规则为(X为当前国家,i为下一个国家)

a. 如果 x,i 两国之间没有路,则不走
b. 如果 i 国文化已经学过,则不走
c. 如果 i 国文化对 x 国文化排斥,则不走
否则,dfs下一个国家

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;const int MAXN = 105;
int n, k, m, s, t;
int c[MAXN];       // c[i] 记录第i个国家的文化;
int a[MAXN][MAXN]; // a[i][j]=1 表示第i种文化对第j种文化排斥。0表示不排斥
int e[MAXN][MAXN]; // e[i][j]=d 表示第i个国家到第j个国家之间有一条边,长度为d
int dis[MAXN];     // dis[i] 记录从起点国到第i个国家的最短距离
bool vis[MAXN];    // vis[i] = true 表示第i种文化已经学过/*
深搜dfs:
1、从起点国家开始,dfs每一个国家到起点国家的最短距离。
2、向下dfs时的判断规则为(X为当前国家,i为下一个国家)
a. 如果 x,i 两国之间没有路,则不走
b. 如果 i 国文化已经学过,则不走
c. 如果 i 国文化对 x 国文化排斥,则不走
入参:x为当前国家:d为x国到起点国的最短距离
*/
void dfs(int x, int d)
{if (d >= dis[x])  return;	// 如果x国当前传进来的距离d大于之前算过的最短距离 dis[x], 则返回,不再计算后续路径dis[x] = d; // 否则,更新x国到起点国的最段距离// 继续向下深搜dfsif (x == t) return; // 如果当前已达到终点国,则不继续深搜for (int i = 1; i <= n; i ++){				    // 否则,枚举每一个国家 iif( e[x][i] == INF ) continue;  // 如果x,i两国之间没有路,则枚举下一个国家if( vis[c[i]] == true ) continue;       // 如果 i 国文化已经学过,则枚举下一个国家if( a[c[i]][c[x]] == 1 )  continue; // 如果 i 国文化对 x 国文化排斥,则枚举下一个国家vis[c[i]] = true;  // 对 i 国深搜之前,先标记该国文化为已访问dfs(i, d + e[x][i]);vis[c[i]] = false; // 推出dfs时恢复现场}
}int main()
{scanf("%d %d %d %d %d", &n, &k, &m, &s, &t);for(int i = 1; i <= n; i++)  scanf("%d", &c[i]);   //国家 i的文化为 Cifor(int i = 1; i <= k; i++)for(int j = 1; j <= k; j++)scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 jmemset(dis, 0x3f, sizeof(dis)); // 初始化每个国家到起点国的最短距离为正无穷memset(e, 0x3f, sizeof(e));     // 初始化国与国之间的边为正无穷for(int i = 1; i <= m; i++){int u, v, d;scanf("%d %d %d", &u, &v, &d);e[u][v] = min(e[u][v], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值存边e[v][u] = min(e[v][u], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值存边}vis[c[s]] = true; // 起点国的文化标记为已学过dfs(s, 0);        // 从起点国s进行深搜,当前最短距离为0if (dis[t] == INF)  printf("-1\n");else  printf("%d\n", dis[t]);return 0;
}
解法二、floyd 求最短路

核心要点:
1、在处理三重循环之前,先把边的关系梳理完毕。即使 e[i][j] 有值,但如果 i 和 j 属于不同的文化,也说明这条路走不通,故应将 e[i][j] 改为无穷大

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;const int MAXN = 105;
int n, k, m, s, t, ans;
int c[MAXN];       // c[i] 记录第i个国家的文化;
int a[MAXN][MAXN]; // a[i][j]=1 表示第i种文化对第j种文化排斥。0表示不排斥
int dis[MAXN][MAXN]; // e[i][j]=d 表示第i个国家到第j个国家之间有一条边,长度为dint main()
{scanf("%d %d %d %d %d", &n, &k, &m, &s, &t);memset(dis, 0x3f, sizeof(dis));     // 初始化国到国之间的最短距离为正无穷for(int i = 1; i <= n; i++)  scanf("%d", &c[i]);   //国家 i的文化为 Cifor(int i = 1; i <= k; i++)for(int j = 1; j <= k; j++)scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 jfor(int i = 1; i <= m; i++){int u, v, d;scanf("%d %d %d", &u, &v, &d);dis[u][v] = min(dis[u][v], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值存边dis[v][u] = min(dis[v][u], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值存边}for (int i = 1; i <= n; i ++)for (int j = 1; j <= n; j ++)if(a[c[i]][c[j]] == 1)  dis[i][j] = INF; // 如果 i 和 j 属于不同的文化,则此路也不通for (int k = 1; k <= n; k ++)for (int i = 1; i <= n; i ++)for (int j = 1; j <= n; j ++)if (dis[i][j] > dis[i][k] + dis[k][j])dis[i][j] = dis[i][k] + dis[k][j];if (dis[s][t] == INF)  printf("-1");else  printf("%d\n", dis[s][t]);return 0;
}
解法三、dijkstra

由于是求 单源最短路,所以也可以用 dijkstra 算法来完成。如下供参考

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;const int MAXN = 105;
int n, k, m, s, t, ans;
int c[MAXN];       // c[i] 记录第i个国家的文化;
int a[MAXN][MAXN]; // a[i][j]=1 表示第i种文化对第j种文化排斥。0表示不排斥
int e[MAXN][MAXN]; // e[i][j]=d 表示第i个国家到第j个国家之间有一条边,长度为d
int dis[MAXN];     // dis[i]=d 表示第i个国家到起点国最段距离为d
bool vis[MAXN];    // vis[i] = true 表示第i种文化已经学过/*
朴素 dijkstra
*/
void dijkstra(int u)
{int minval, k = -1;for(int i = 1; i <= n - 1; i++)  // 在剩余的顶点中,挑选顶点k,使dis[k]最小。做 n-1 轮{minval = INF;for(int j = 1; j <= n; j++){if( (vis[j] == false) && ( dis[j] < minval ) ){minval = dis[j];k = j;}}if(k == -1)  return;  // 如果本轮未找到最小值,则退出vis[k] = true;for(int j = 1; j <= n; j++)  // 使用本轮最短距离更新剩余每一个城市的最短距离dis[j] = min(dis[j], dis[k] + e[k][j]);}
}int main()
{scanf("%d %d %d %d %d", &n, &k, &m, &s, &t);memset(e, 0x3f, sizeof(e));     // 初始化国到国之间的最短距离为正无穷memset(dis, 0x3f, sizeof(dis));     // 初始化国到国之间的最短距离为正无穷for(int i = 1; i <= n; i++)  scanf("%d", &c[i]);   //国家 i的文化为 Cifor(int i = 1; i <= k; i++)for(int j = 1; j <= k; j++)scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 jfor(int i = 1; i <= m; i++){int u, v, d;scanf("%d %d %d", &u, &v, &d);e[u][v] = min(e[u][v], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值e[v][u] = min(e[v][u], d);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值}for(int i = 1; i <= n; i ++)for(int j = 1; j <= n; j ++)if( a[c[i]][c[j]] == 1 )  e[i][j] = INF;  // 如果两个国家之间文化排斥,即使i->j有边也走不通,故直接改为正无穷for(int i = 1; i <= n; i++)  dis[i] = e[i][s]; // 先用每一个国家到s国的边作为最段距离初始化vis[s] = true;dis[s] = 0; // 起点到起点的距离为0dijkstra(s);if (dis[t] == INF)  printf("-1");else  printf("%d\n", dis[t]);return 0;
}

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

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

相关文章

C++程序设计:new和malloc的区别

new和malloc的区别 1.用法和语法2.类型安全性3.初始化4.分配数组5.异常处理示例代码 1.用法和语法 new 是 C 中的运算符&#xff0c;而 malloc 是 C 语言中的函数。new 用于动态分配单个对象或数组&#xff0c;并且在分配内存后调用对象的构造函数进行初始化。malloc 用于动态分…

golang学习笔记(内存模型和分配机制)

操作系统的存储管理 虚拟内存管理 虚拟内存是一种内存管理技术&#xff0c;它允许操作系统为每个进程提供一个比实际物理内存更大的地址空间。这个地址空间被称为虚拟地址空间&#xff0c;而实际的物理内存则被称为物理地址空间。使用虚拟内存有以下几点好处&#xff1a; 内…

C# 用户控件UserControl事件解绑资源释放

用户控件继承子 UserControl 。 现在有个业务需求在UserControl 所在的窗体关闭时解除事件HMouseDown绑定。 因没有相关的Close事件。后来本人想了一个办法在 ROICtlDesigner类的 Dispose 方法中执行相关的释放代码 比如解除事件绑定 释放资源 public partial class ROICt…

git 第一次安装设置用户名密码

git config --global user.name ljq git config --global user.email 15137659164qq.com创建公钥命令 输入后一直回车 ssh-keygen -t rsa下面这样代表成功 这里是公钥的 信息输入gitee 中 输入下面命令看是否和本机绑定成功 ssh -T gitgitee.com如何是这样&#xff0c;恭喜…

Ubuntu系统重装

1、删除相关卷&#xff0c;ubuntu引导项&#xff08;select disk、assign letter的方法&#xff09; Ubuntu20.04重装系统过程&#xff08;多图&#xff0c;含保存文件卸载旧系统安装新系统&#xff09;_ubuntu重装系统-CSDN博客 2、分配空间 efi 1024MB 逻辑分区 swap 8*1…

基于51单片机PWM控制直流电机—数码管显示

基于51单片机PWM控制直流电机 &#xff08;仿真&#xff0b;程序&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.L298驱动直流电机&#xff1b; 2.数码管显示转动方向和PWM占空比&#xff08;0-100%&#xff09;&#xff1b; 3.按键控制PWM占空比来加/…

20232803 2023-2024-2 《网络攻防实践》实践八报告

目录 1. 实践内容2. 实践过程2.1 动手实践任务一2.2 动手实践任务二&#xff1a;分析Crackme程序2.2.1 crackme1.exe2.2.2 crackme2.exe 2.3 分析实践任务一2.4 分析实践任务二 3. 学习中遇到的问题及解决4. 学习感悟、思考等 1. 实践内容 动手实践任务一&#xff1a;对提供的r…

Vue入门到关门之第三方框架elementui

1、什么是ElementUI&#xff1f; Element UI 是一个基于 Vue.js 的组件库&#xff0c;它提供了丰富的 UI 组件和一套完整的解决方案&#xff0c;用于快速构建现代化的 Web 应用程序。Element UI 的目标是帮助开发者快速构建出美观、易用的界面&#xff0c;并提供了丰富的组件&…

四种粒子群算法的Matlab实现

粒子群算法&#xff0c;又称为粒子群优化&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;&#xff0c;是一种基于群体智能的优化算法。它最初由James Kennedy和Russell Eberhart于1995年提出&#xff0c;灵感来源于鸟群捕食行为的研究。在PSO中&#…

R语言实战——中国职工平均工资的变化分析——相关与回归分析

链接: R语言学习—1—将数据框中某一列数据改成行名 R语言学习—2—安德鲁斯曲线分析时间序列数据 R语言学习—3—基本操作 R语言学习—4—数据矩阵及R表示 R语言的学习—5—多元数据直观表示 R语言学习—6—多元相关与回归分析 1、源数据 各行业平均工资变化 各地区平均工资…

list 的模拟实现

目录 1. list 的实现框架 2. push_back 3. 迭代器 4. constructor 4.1. default 4.2. fill 4.3. range 4.4. initializer list 5. insert 6. erase 7. clear 和 destructor 8. copy constructor 9. operator 10. const_iterator 10.1. 普通人的处理方案 10.2. …

运维的边缘计算

运维的边缘计算是指在靠近物或数据源头的一侧&#xff0c;采用网络、计算、存储、应用核心能力为一体的开放平台&#xff0c;进行运维管理和服务的计算模式。具体来说&#xff0c;边缘计算在运维领域的应用主要体现在以下几个方面&#xff1a; 超低时延&#xff1a;在传统的云…

数据库复习1

1.试述数据、数据库、数据库管理系统、数据库系统的概念 1.数据(Data): 数据是关于事物的符号表示或描述。它可以是任何事实、观察或者测量的结果&#xff0c;如数字、字符、声音、图像等。数据在没有上下文的情况下可能没有明确的意义。 2.数据库(Database): 数据库是一个持…

Linux——socket编程之tcp通信

前言 前面我们学习socket的udp通信&#xff0c;了解到了socket的概念与udp的实现方法&#xff0c;今天我们来学习一下面向连接的tcp通信。 一、tcp套接字创建 UDP和TCP都是通过套接字&#xff08;socket&#xff09;来实现通信的&#xff0c;因此TCP也得使用socket()接口创建…

时间复杂度_空间复杂度

时间复杂度_空间复杂度 1.算法效率 算法效率分析分为两种:第一种是时间效率&#xff0c;第二种是空间效率。 时间效率被称为时间复杂度&#xff0c;而空间效率被称作空间复杂度。时间复杂度主要衡量的是一个算法的运行速度&#xff0c;而空间复杂度主要衡量一个算法所需要的…

vue什么是服务端渲染(SSR)

Vue服务端渲染&#xff08;SSR&#xff09;在优化SEO方面有着显著的优势&#xff0c;因为它允许搜索引擎直接访问服务器渲染的页面&#xff0c;从而更容易解析页面内容。以下是一些关于如何使用Vue SSR优化SEO的建议&#xff1a; 为每个URL生成静态HTML&#xff1a;Vue SSR允许…

达摩院 2025届暑期实习 大模型算法

文章目录 写在前面一面/技术面 2024/4/7 晚上19:00-20:00二面/技术面 2024/4/23 早上11:15-12:15 写在前面 学校情况&#xff1a;211本中9硕&#xff0c;本硕都是计算机科班&#xff0c;但研究方向并不是NLP&#xff0c;而是图表示学习论文情况&#xff1a;1A(NeurIPS)1B(ICDM…

C#技巧之同步与异步

区别 首先&#xff0c;同步就是程序从上往下顺序执行&#xff0c;要执行完当前流程&#xff0c;才能往下个流程去。 而异步&#xff0c;则是启动当前流程以后&#xff0c;不需要等待流程完成&#xff0c;立刻就去执行下一个流程。 同步示例 创建一个窗体&#xff0c;往窗体里…

面试 Java 基础八股文十问十答第二十八期

面试 Java 基础八股文十问十答第二十八期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;动态代理是什么&am…

2131 - 枚举-练习-涂国旗

2131 - 枚举-练习-涂国旗 c刷题 超能力编程 分析 枚举涂w的底边和涂b的底边即可 剩下的部分都涂r 数据范围这么小,暴力枚举&#xff0c;代码简单难度低。搜索什么的用不着啦&#xff01; 那么问题来了&#xff1a;怎么枚举呢&#xff1f; 我们只要枚举白与蓝、蓝与红的边界&…