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国到起点国的最段距离

    // 继续向下深搜dfs
    if (x == t) return; // 如果当前已达到终点国,则不继续深搜
    for (int i = 1; i <= n; i ++)
    {				    // 否则,枚举每一个国家 i
        if( 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的文化为 Ci
    for(int i = 1; i <= k; i++)
        for(int j = 1; j <= k; j++)
            scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 j

    memset(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进行深搜,当前最短距离为0

    if (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个国家之间有一条边,长度为d


int 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的文化为 Ci

	for(int i = 1; i <= k; i++)
        for(int j = 1; j <= k; j++)
            scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 j

    for(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的文化为 Ci

    for(int i = 1; i <= k; i++)
        for(int j = 1; j <= k; j++)
            scanf("%d", &a[i][j]);  //a[i][j] = 1 表示文化 i 排斥外来文化 j

    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);  // 邻接矩阵:由于两个国家之间可能有多条道路,所以读入时取最小值
    }

    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; // 起点到起点的距离为0
    dijkstra(s);

    if (dis[t] == INF)  printf("-1");
    else  printf("%d\n", dis[t]);

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【附poc】新中新中小学智慧校园信息管理系统存在SQL注入漏洞

新中新中小学智慧校园信息管理系统介绍&#xff1a;新中新利用云服务技术同时借鉴互联网模式&#xff0c;围绕基础教育信息化、智慧化建设&#xff0c;把线下业务和线上业务结合&#xff0c;为教育主管部门、校园管理者、教师、学生以及家长提供具有教务管理功能的平台化、移动…

基于TL431基准电压源的可调恒压恒流源的Multisim电路仿真设计

1、线性电源的工作原理 在我们日常应用里&#xff0c;直流电是从市电或电网中的交流电获取的。例如15V直流电压源、24V直流电压源等等。交流电变为直流电的过程大概分为一下几步&#xff1a; 首先&#xff0c;交流电通过变压器降低其电压幅值。接着&#xff0c;经过整流电路进…

八、Linux进程检测与控制

章节目标 了解进程和程序的关系了解进程的特点能够使用top动态查看进程信息能够使用ps静态查看进程信息能够使用kill命令给进程发送信号能够调整进程的优先级&#xff08;扩展&#xff09; 引言 在运维的日常工作中&#xff0c;监视系统的运行状况是每天例行的工作&#xff…

Spring IoCDI (1)

目录 一、IoC & DI入门 1、Spring是什么 &#xff08;1&#xff09;什么是容器&#xff1f; &#xff08;2&#xff09;什么是IoC&#xff1f; 二、IoC介绍 1、传统程序开发 2、解决方案 3、IoC程序开发 4、IoC优势 三、DI介绍 通过前面的学习&#xff0c;我们知…

分布式与一致性协议之ZAB协议(二)

ZAB协议 ZAB协议是如何实现操作地顺序性的&#xff1f; 如果用一句话解释ZAB协议到底是什么&#xff0c;我觉得它是能保证操作顺序性的、基于主备模式的原子广播协议。 接下来&#xff0c;还是以指令X、Y为例具体演示一下&#xff0c;帮助你更好地理解为什么ZAB协议能实现操作…

力扣每日一题113:路径总和||

题目 中等 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…

【R语言数据分析】函数

目录 自定义函数 apply函数 分类汇总函数aggregate 自定义函数 R语言中的自定义函数更像是在自定义一种运算规则。 自定义函数的语法是 函数名 函数体 } 比如 表示定义了一个名为BMI_function的函数&#xff0c;这个函数代表了一种运算规则&#xff0c;就是把传入的x和…

stm32开发之netxduo网口通讯,网线热插拔处理

前言 在使用netxduo组件时&#xff0c;如果在上电过程中&#xff0c;未插入网线&#xff0c;eth驱动使能过程中未正常初始化本次使用以下几种方式进行设置 问题原因 使用定时器事件回调方式 网络组件中进行调整 /** Copyright (c) 2024-2024&#xff0c;shchl** SPDX-Licen…

openGL

open Graphics Library 核心是一个c库&#xff0c;同时支持多语言的派生。 可编程管线&#xff0c; 状态机&#xff08;State Machine&#xff09;是一种数学模型&#xff0c;用于描述对象在不同状态下的行为及状态之间的转换关系。状态机由一组状态&#xff08;States&#…

2010NOIP普及组真题 2. 接水问题

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1950 解法一、朴素模拟 核心思想&#xff1a; 朴素模拟&#xff1a; 1、先给每个b[i]水龙头分配一个人a[i]&#xff0c;b[i] 表示水龙头的剩余时间。同时标记该水龙头为 used 使用中 2…

深入解析:匹配网络(Matching Networks)的原理和应用

匹配网络&#xff08;Matching Networks&#xff09; 深入解析&#xff1a;匹配网络&#xff08;Matching Networks&#xff09;的原理和应用匹配网络的核心原理工作原理算法流程 匹配网络的实现应用示例结论 深入解析&#xff1a;匹配网络&#xff08;Matching Networks&#…

01_SpringBoot简单搭建入门程序

目录 1、先创建一个java项目2、导入依赖3、将Java项目修改为SpringBoot项目4、编写一个测试的Controller5、测试(创建一个*.http的文件)方式1&#xff1a;方式2&#xff1a;可以直接在浏览器访问该地址方式3&#xff1a;使用postman也可以 1、先创建一个java项目 我的项目结构…

FlinkSql使用ES sink并指定主键,为什么数据还是会被覆盖?

FlinkSql使用ES sink并指定主键&#xff0c;为什么数据还是会被覆盖&#xff1f; 1. 问题描述 根据ES connector文档中的描述&#xff0c;创建ES表并指定主键后将采用upsert模式。 但是在实际的使用过程中却发现部分数据仍然存在被直接覆盖的问题。 举个例子&#xff0c;假如…

NumPy库与PyTorch库的异同点

目录 1.单位的创建和操作 1.创建 2.形状变换 2.数学和统计操作 1.矩阵乘法 2.广播 3.统计计算 3.GPU支持 4.在深度学习中的作用 5.应用范围 NumPy库为数组服务&#xff0c;PyTorch库为张量服务&#xff0c;这是最本质的区别。 1.单位的创建和操作 1.创建 NumPy:使…

【busybox记录】【shell指令】md5sum

目录 内容来源&#xff1a; 【GUN】【md5sum】指令介绍 【busybox】【md5sum】指令介绍 【linux】【md5sum】指令介绍 使用示例&#xff1a; 128位MD5 - 默认输出 128位MD5 - 将每个文件当做二进制处理 128位MD5 - 从文件中读取MD5值并做检查 128位MD5 - 创建一个BSD风…

浅谈OpenCV 粗略计算工件轮廓面积和外接圆直径(Emgu.CV)

前言 最近领导在做库房工具管理这块的功能&#xff0c;希望能集成OpenCV 粗略的计算出工具的长度&#xff0c;以方便用户再归还工具的时候&#xff0c;提示用户该放在那种尺寸的盒子里面&#xff0c;这便是这篇文章的由来。 我们的系统是基于.net开发的&#xff0c;所以采用的是…

项目管理-项目采购管理1/2

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 1.项目采购管理-主要内容 项目采购管理过程--重点&#xff1a; ①ITTO 输入&#xff0c;输出工具和技术。 ②问题和解决方案。 ③论文…

【白话机器学习系列】白话特征向量

白话特征向量 一个方阵 A A A 与列向量 v v v 的乘积会生成一个新的列向量。这个新向量通常与原向量有着不同的方向&#xff0c;矩阵在这里代表一个线性变换。然而&#xff0c;某些向量会保持其原始方向。我们称这种向量为矩阵 A A A 的特征向量&#xff08;eigenvector&…

python数据分析——业务指标分析

业务指标分析 前言一、业务指标分析的定义二、业务问题构建问题构建的要求 三、业务问题的识别在识别问题的阶段对于企业内部收益者的补充&#xff1a; 四、竞争者分析标题竞争者分析的内容&#xff1a;标题竞争者分析目的&#xff1a;案例&#xff1a; 黑莓公司为什么会消亡&a…

dynamic_cast 静态转换

dynamic_cast 静态转换 const_cast 常量转换 重新解释转换(reinterpret_cast) 最不安全