【图论】洛谷P5676 GZOI2017D1T2 小z玩游戏 题解(代码不保证AC)

一、准备材料

题目传送门

二、初步分析

看看标题前两个字是啥?所以本题需要用图论知识解决。
将题目给出的线索转化为一个有向图,再对于每个 i i i,判断 e i e_i ei w i w_i wi 是否在同一个强连通分量里即可。
那么如何去建立这个有向图呢?后面第三部分会讲,在此不再赘述。

三、深度优先搜索DFS思路

题目说小z只会玩有趣程度是自己兴奋程度整数倍的游戏,由于游戏实际上有好玩的也有不好玩的,玩完第 i i i 个游戏后,小z的兴奋程度会变为 e i e_i ei
那么我们将兴奋程度 x x x 和自己整数倍的有趣程度 k x kx kx 建边 ( k ∈ N ∗ ) (k \isin N^*) (kN) w i w_i wi i i i 建边,再将 i i i e i e_i ei 建边即可。
题目说 n n n w i w_i wi e i e_i ei 的范围都是 100000 100000 100000,那么节点的数量就是 300000 300000 300000,如果使用邻接矩阵是妥妥的MLE,所以应使用链式前向星存图。
为了区分相等的数值(如 w 12207 w_{12207} w12207 c 12207 c_{12207} c12207 的值均为 12207 12207 12207 的情况),我们将有趣程度加上 100000 100000 100000,游戏编号加上 200000 200000 200000 再去建边。
如果你想优化,在第五部分会专门去讲,在此不再赘述。
当然这种方法是绝对会TLE并且拿 0 0 0 分的,如果你是追求得分的玩家,直接看第四部分就行了
维护一个集合,以 1 1 1 为起点深度优先搜索,如果某个结点的儿子是一个被访问过且大于 200000 200000 200000 的结点(就是游戏编号),那么我们将该结点插入集合。最后输出集合的大小。
代码:

#include<bits/stdc++.h>
using namespace std;
int t,n;
int w[114514],ex[114514];
int head[300006],e[8888888],nxt[8888888],idx;
void add(int u,int v){e[idx]=v;nxt[idx]=head[u];head[u]=idx;idx++;return;
}
set<int>st;
bool vis[300006];
void dfs(int x){for(int i=head[x];i!=-1;i=nxt[i]){if((!vis[e[i]])&&e[i]<=200000){vis[e[i]]=1;dfs(e[i]);vis[e[i]]=0;}else st.insert(e[i]);}return;
}
int main(){memset(head,-1,sizeof(head));scanf("%d",&t);for(int i=1;i<=100000;i++)for(int ii=i;ii<=100000;ii+=i)add(i,ii+100000);while(t--){st.clear();for(int i=100001;i<=300000;i++)head[i]=-1;idx=1166750;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++){scanf("%d",&ex[i]);add(w[i]+100000,i+200000);add(i+200000,ex[i]);}memset(vis,0,sizeof(vis));dfs(1);printf("%d\n",st.size());}return 0;
}

四、Tarjan缩点思路

这个是正解思路,但是俺不知道为啥只得了 30 30 30 分……(雾
按第三部分所说的方法建图以后,以 1 1 1 为起点跑一遍Tarjan,然后再对于每个 i i i,判断 e i e_i ei w i w_i wi是否在同一个强连通分量里即可。

#include<bits/stdc++.h>
using namespace std;
int t,n,cnt;
int w[114514],ex[114514];
int head[300006],e[8888888],nxt[8888888],idx;
void add(int u,int v){e[idx]=v;nxt[idx]=head[u];head[u]=idx;idx++;return;
}
int step;
stack<int>st;
int dnf[300006],low[300006];
bool in_st[300006];
void tarjan(int x){int tmp;step++;dnf[x]=low[x]=step;st.push(x);in_st[x]=1;for(int i=head[x];i!=-1;i=nxt[i]){tmp=e[i];if(!dnf[tmp]){tarjan(tmp);low[x]=min(low[x],low[tmp]);}else if(in_st[tmp])low[x]=min(low[x],dnf[tmp]);}if(low[x]==dnf[x]){do{tmp=st.top();st.pop();in_st[tmp]=0;}while(tmp!=x);}return;
}
int main(){memset(head,-1,sizeof(head));scanf("%d",&t);for(int i=1;i<=100000;i++)for(int ii=i;ii<=100000;ii+=i)add(i,ii+100000);while(t--){for(int i=100001;i<=300000;i++)head[i]=-1;idx=1166750;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++){scanf("%d",&ex[i]);add(w[i]+100000,i+200000);add(i+200000,ex[i]);}memset(dnf,0,sizeof(dnf));step=0;tarjan(1);cnt=0;for(int i=1;i<=n;i++)if(low[w[i]+100000]==low[ex[i]])cnt++;printf("%d\n",cnt);}return 0;
}

五、建图优化

相信大家都是从第三部分直接跳过来的吧!看完记得回去哦!
其实我们没必要去建立游戏编号的结点,直接将 w i w_i wi e i e_i ei 建边即可。因为在第三部分中,对于 i i i w i w_i wi e i e_i ei 之间建立的边都是唯一的,如果出现 w 12207 = w 12725 w_{12207}=w_{12725} w12207=w12725 c 12207 = c 12725 c_{12207}=c_{12725} c12207=c12725 这样的情况,那么玩这两个游戏本质上是一样的,不需要再去两个游戏编号分别遍历两次。如果像第三部分那样建边,会很浪费评测时间。
但是,如果你是选择使用DFS的玩家,就不能使用这种方法了,因为DFS方法中集合统计的就是游戏编号,这个值是必需的。
对于第四部分中的方法,优化代码如下(为啥只有 30 30 30 分捏~)

#include<bits/stdc++.h>
using namespace std;
int t,n,cnt;
int w[114514],ex[114514];
int head[200006],e[8888888],nxt[8888888],idx;
void add(int u,int v){e[idx]=v;nxt[idx]=head[u];head[u]=idx;idx++;return;
}
int step;
stack<int>st;
int dnf[200006],low[200006];
bool in_st[200006];
void tarjan(int x){int tmp;step++;dnf[x]=low[x]=step;st.push(x);in_st[x]=1;for(int i=head[x];i!=-1;i=nxt[i]){tmp=e[i];if(!dnf[tmp]){tarjan(tmp);low[x]=min(low[x],low[tmp]);}else if(in_st[tmp])low[x]=min(low[x],dnf[tmp]);}if(low[x]==dnf[x]){do{tmp=st.top();st.pop();in_st[tmp]=0;}while(tmp!=x);}return;
}
int main(){memset(head,-1,sizeof(head));scanf("%d",&t);for(int i=1;i<=100000;i++)for(int ii=i;ii<=100000;ii+=i)add(i,ii+100000);while(t--){for(int i=100001;i<=200000;i++)head[i]=-1;idx=1166750;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++){scanf("%d",&ex[i]);add(w[i]+100000,ex[i]);}memset(dnf,0,sizeof(dnf));step=0;tarjan(1);cnt=0;for(int i=1;i<=n;i++)if(low[w[i]+100000]==low[ex[i]])cnt++;printf("%d\n",cnt);}return 0;
}

如果博客有错误,或者发现了代码中的问题,请联系我,我会尽快修正!压力马斯内!

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

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

相关文章

手动修改zk类型的kafka offset

手动修改zk类型的 offset: 连接到ZooKeeper ./zkCli.sh -server ..123:2181,.…87.124:2181,1*.*.87.125:2181 查找并修改ae_spark这个topic的消费者组的offset值 对于每个分区&#xff08;0、1、2&#xff09;&#xff0c;需要分别查看和修改offset值 查看和修改分区0的offs…

算法-模型似然值计算

1、C示例代码 for (int i 0; i < model_size; i) {// 模型i更新imm_ukf_[i].Update(Z, ntime);// 模型i观测值与预测值的差Eigen::VectorXd Zminus imm_ukf_[i].Get_Zminus();// 模型i的预测协方差矩阵Eigen::MatrixXd S imm_ukf_[i].Get_S();// 计算模型i的似然值model_…

Qt坐标系统之三个坐标系和两个变换

前言 Qt坐标系统由QPainter类控制。它和QPaintDevice和QPaintEngine类一起构成Qt绘图系统的基础。QPainter用于执行绘图操作&#xff0c;QPaintDevice是QPainter用来绘制的一个二维空间的抽象&#xff0c;QPaintEngine提供在不同设备绘图的接口。 Qt 的坐标分为逻辑坐标和物理…

True XML cookbook

打开题目 看到登录口 随便输入admin&#xff0c;123456&#xff0c;然后抓包试一下 先按原来那道题的payload进行测试&#xff0c;payload和结果如下&#xff1a; <?xml version"1.0" ?> <!DOCTYPE llw [ <!ENTITY file SYSTEM "file:///flag&…

分布式 - 主从复制技术详解及时延处理

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有疑问和建议&#xff0c;请私信或评论留言&#xff01; 主从复制技术详解及时…

k8s教程

1. k8s框架 - kubernetes的架构- Control Plane: 控制K8S集群的组件。- Api Server: 集群的访问入口。- etcd: 存储集群的数据。一般情况下&#xff0c;只有API-SERVER会访问.- Control Manager: 维护集群的状态。- Scheduler: 负责Pod的调度功能。- Wor…

性能测试常见故障和解决思路

一、性能问题分析流程 1、查看服务器的CPU、内存 、负载等情况&#xff0c;包括应用服务器和数据库服务器 2、查看数据库健康状态&#xff0c;数据库死锁、连接池不释放 3、查看项目日志&#xff08;查看无报错现象&#xff09; 4、查看jvm的gc等情况 二、内存溢出 &…

python数组列表操作简记二

python数组列表操作简记二 一、列表配对组合为新列表或字典1.1多个列表配对组合为新列表1.2两个列表配对转换为字典 二、数组加减乘除运算2.1一维数组加减除运算2.2一维数组乘法运算 三、数组切片读取3.1一维数组切片读取3.2二维数组切片读取3.3三维数组切片读取 四、数组简单筛…

SSL/TLS协议信息泄露漏洞修复

概述&#xff1a;CVE-2016-2183 是一个涉及 SSL/TLS 协议信息泄露的漏洞&#xff0c;也被称为 "SWEET32" 攻击。该漏洞利用了某些对称加密算法&#xff08;如 3DES&#xff09;的弱点&#xff0c;攻击者可以通过捕获和分析大量的加密流量&#xff0c;可能会恢复明文数…

Sqlite3数据库表内数据批量读取操作---sqlite3_stmt机制

0、引言 在前面两篇文章已经对数据环境搭建、数据批量写入库中进行了较为详细的讲解。因此&#xff0c;基于前两篇文章内容的基础上&#xff0c;本文主要从数据库中批量数据读取操作进行梳理讲解。 嵌入式数据库SQLite 3配置使用详细笔记教程_sqlite3-CSDN博客 SQLite 3 优化批…

【机器学习】4. 相似性比较(二值化数据)与相关度(correlation)

SMC Simple Matching Coefficient 评估两组二进制数组相似性的参数 SMC (f11 f00) / (f01f10f11f00) 其中&#xff0c;f11表示两组都为1的组合个数&#xff0c;f10表示第一组为1&#xff0c;第二组为0的组合个数。 这样做会有一个缺点&#xff0c;假设是比较稀疏的数据&…

<数据集>流水线纸箱识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;1395张 标注数量(xml文件个数)&#xff1a;1395 标注数量(txt文件个数)&#xff1a;1395 标注类别数&#xff1a;2 标注类别名称&#xff1a;[GreenCarton,RedCarton] 序号类别名称图片数框数1GreenBox131728482R…

解析XML格式数据

解析XML格式数据主要涉及到将XML文档转换为程序可以处理的数据结构&#xff0c;这通常通过使用特定的解析技术来实现。在Java中&#xff0c;解析XML数据主要有四种方法&#xff0c;分别是DOM&#xff08;Document Object Model&#xff09;、SAX&#xff08;Simple API for XML…

力扣 | 最长公共子序列 | 动态规划 | 最长公共子序列长度、最长公共子序列

文章目录 一、1143. 最长公共子序列二、求最长公共子序列三、变式一、1035. 不相交的线二、1312. 让字符串成为回文串的最少插入次数 一、1143. 最长公共子序列 LeetCode&#xff1a;1143. 最长公共子序列 这是一道典型的二维动态规划问题&#xff0c;甚至面试都能被面到。 这…

下载文件设置响应头

参考链接&#xff1a;关于URL编码 1、概述 一般要对文件名称编码&#xff08;主要是中文名称和特殊符号编码的问题&#xff09;&#xff0c;不然下载的时候会出异常&#xff0c;异常在后面 package com.mocha.order.util;import com.mocha.order.constant.BrowserConstant; …

【15】bat脚本备份windows的部署文件

1、请安装D:\7-Zip\7z.exe压缩工具,sshfs工具 2、通过挂载远程服务器存储文件夹,将部署文件压缩到指定备份路径 3、指定备份路径只保存20个文件,超过定期删除多余的 4、部署文件备份完成后,卸载远程存储文件夹 @echo off setlocal:: 备份web、mysql、redis、nginx :: folde…

Linux buffer/cache

清除方法 echo 1 > /proc/sys/vm/drop_caches # 仅清除页面缓存 echo 2 > /proc/sys/vm/drop_caches # 清除目录项和inode echo 3 > /proc/sys/vm/drop_caches # 清除页面缓存、目录项以及inode 下面了解一下这几种都是什么,简单理解&#xff0c;目录项和inode&…

C#关于多线程的线程问题

using System.Text; ​ namespace 平时练习8._19day06 {internal class Program{static async Task Main(string[] args){Console.WriteLine(Thread.CurrentThread.ManagedThreadId );StringBuilder sb new StringBuilder();for (int i 0; i < 10000; i){sb.Append("…

坚持绿色发展的上海智算中心,稳步推进中

自今年年初正式封顶以来&#xff0c;云端股份上海智算中心在外墙及内部的建设进展顺利。这座智算中心地理位置优越&#xff0c;正逐步成为推动数字经济发展的重要力量。 位置优势 云端股份上海智算中心毗邻智慧岛数据产业园&#xff0c;是崇明区目前建设的唯一一座智算中心&am…

多功能秒达工具箱全开源源码,可自部署且完全开源的中文工具箱

简介&#xff1a; 多功能秒达开源工具箱源码&#xff0c;&#xff0c;可自部署且完全开源的中文工具箱&#xff0c;永远的自由软件&#xff0c;轻量级运行&#xff0c;全平台支持&#xff08;包括ARMv8&#xff09;&#xff0c;完全类似 GPT 的支持&#xff0c;与高效的 UI 高…