那就别担心了(DFS优化)30行代码简单易懂

news/2024/11/2 1:33:43/

下图转自“英式没品笑话百科”的新浪微博 —— 所以无论有没有遇到难题,其实都不用担心。

博主将这种逻辑推演称为“逻辑自洽”,即从某个命题出发的所有推理路径都会将结论引导到同一个最终命题(开玩笑的,千万别以为这是真正的逻辑自洽的定义……)。现给定一个更为复杂的逻辑推理图,本题就请你检查从一个给定命题到另一个命题的推理是否是“逻辑自洽”的,以及存在多少种不同的推理路径。例如上图,从“你遇到难题了吗?”到“那就别担心了”就是一种“逻辑自洽”的推理,一共有 3 条不同的推理路径。

输入格式:

输入首先在一行中给出两个正整数 N(1<N≤500)和 M,分别为命题个数和推理个数。这里我们假设命题从 1 到 N 编号。

接下来 M 行,每行给出一对命题之间的推理关系,即两个命题的编号 S1 S2,表示可以从 S1 推出 S2。题目保证任意两命题之间只存在最多一种推理关系,且任一命题不能循环自证(即从该命题出发推出该命题自己)。

最后一行给出待检验的两个命题的编号 A B

输出格式:

在一行中首先输出从 A 到 B 有多少种不同的推理路径,然后输出 Yes 如果推理是“逻辑自洽”的,或 No 如果不是。

题目保证输出数据不超过 109。

输入样例 1:

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

输出样例 1:

3 Yes

输入样例 2:

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

输出样例 2:

3 No

代码长度限制

16 KB

时间限制

400 ms

内存限制

 DFS

30行代码(运行超时23分)最后一个过不了

#include<bits/stdc++.h>
using namespace std;
const int maxn = 500 + 10;
int N, M, K, A, B, D, NUM;
vector<vector<int>>v(maxn);
bool ok = true;
int DFS(int start, int enl)
{if (start == enl) return NUM++;for (auto i : v[start]){if(v[i].size() == 0 && i != enl)ok = false;DFS(i, enl);   }
}int main()
{cin >> N >> M;//N个命题M个推理while (M--){cin >> A >> B;v[A].emplace_back(B);}cin >> K >> D;DFS(K, D);if(!NUM)ok = false;ok ? cout << NUM << ' ' << "Yes" : cout << NUM << ' ' << "No";return 0;
}

画一个图分析一下

如果多连几条线例如:6->5   6->2 ………… 以及当N == 500时,每一条线都连接499个点,直接暴搜会出现一个点重复被访问了多次的情况确实浪费时间,优化也从这方面下手

根据样例:反过来看到1的点无非2 3 4那么可以认为2和3,4到1的路径有1条

5可以到2 3,对于5而言因为我们已知2和3只有1条路径可以到1,所以5到1的路径就应该是Road[2]+Road[3] = 2,递推得Road[7] = Road[4] + Road[6] = Road[4] + Road[5] = 3

因此我们不妨引入一个数组Road记录各点出发到达终点有多少条路径,当我们重复访问到已被记录的点时就省去了再跑一遍的时间,直接反馈答案。

AC代码如下(18ms)

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int maxn = 500 + 10;
int N, M, K, A, B, D, NUM, Road[maxn];
vector<vector<int>>v(maxn);
bool ok = true;
int DFS(int start, int enl)
{if (start == enl)return 1;if (Road[start])return Road[start];for (auto i : v[start]){if (v[i].size() == 0 && i != enl)ok = false;Road[start] += DFS(i, enl);}return Road[start];
}int main()
{IOS cin >> N >> M;//N个命题M个推理while (M--){cin >> A >> B;v[A].emplace_back(B);}cin >> K >> D;DFS(K, D);if (!Road[K])ok = false;ok ? cout << Road[K] << ' ' << "Yes" : cout << Road[K] << ' ' << "No";return 0;
}


http://www.ppmy.cn/news/81867.html

相关文章

Qt——Qt控件之显示窗口-QLCDNumber液晶数字控件的使用总结(例程:Qt液晶数显时钟表)

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! 《项目案例分享》 《极客DIY开源分享》 《嵌入式通用开发实战》 《C++语言开发基础总结》 《从0到1学习嵌入式Linux开发》 《QT开发实战》 《Android开发实战》

OpenCV 算法解析(一)

OpenCV 算法解析 1 图像增强1.1 含义1.2 方法1.2.1 直方图均衡1.2.2 gamma变换 2 除噪2.1 含义2.2 方法2.2.1 高斯滤波2.2.2 均值滤波2.2.3 中值滤波 3 边缘检测3.1 canny 4 HOG特征提取4.1 含义4.2 流程4.3 案例 6 两个比赛6.1 三个功能整合6.2 目标检测6.3 yolov5代码详解 1 …

电子招投标采购系统源码:采购过程更规范,更透明

满足采购业务全程数字化&#xff0c; 实现供应商管理、采购需求、全网寻源、全网比价、电子招 投标、合同订单执行的全过程管理。 电子招标采购&#xff0c;是指在网上寻源和采购产品和服务的过程。对于企业和企业主来说&#xff0c;这是个既省钱又能提高供应链效率的有效方法…

Linux学习 Day5(Linux环境安装/卸载软件)

目录 Linux 软件包管理器 yum 1.什么是软件包 2.关于 rzsz 3.注意事项 4.查看软件包 5.如何安装软件 6. 如何卸载软件 Linux 软件包管理器 yum 1.什么是软件包 在 Linux 下安装软件 , 一个通常的办法是下载到程序的源代码 , 并进行编译 , 得到可执行程序 . 但是这…

交换机密码恢复

通常情况下&#xff0c;可以为交换机设置enable密码来提供安全&#xff0c;在没有enable密码的情况下&#xff0c;无法对交换机修改任何配置&#xff0c;因此&#xff0c;在忘记enable密码的时候&#xff0c;就意味着无法改动交换机信息。但是&#xff0c;如果能够物理上接触到…

Apache Flink 文件上传漏洞 (CVE-2020-17518)

文章目录 一、Apache Flink简介二、漏洞简介三、漏洞复现四、上传jar包getshell 一、Apache Flink简介 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于在无边界和有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行&#xff0c;并能以内存速度和任…

【Java校招面试】实战面经(六)

目录 前言一、如何在N个数中1前K小个数?二、TCP断开连接时为什么需要四次挥手?三、虚拟地址到物理地址的映射过程四、传输用户账号密码时如何加密?五、JSON为什么不存在数据库里?六、Redis是什么?七、Redis的过期策略八、Redis的淘汰策略九、写一个LRUCache十、ThreadLoca…

typescript一些语法糖

单个问号 ? 在定义类型里&#xff0c;代表非必须&#xff0c;可以帮助ide和lint进行静态检查 type UserInfo { username?: string; } 单个问号 ? 用于属性读取&#xff0c;表示如果不存在则返回空&#xff0c;减少一些检查空值的代码。 const valdata?.error.code;…