[CSP-S模拟测试]:循环依赖(拓扑)
题目传送门(内部题148)
输入格式
每个测试点第一行为一个正整数$T$,表示该测试点内的数据组数。
接下来$T$组数据,每组数据第一行一个正整数$n$,表示有引用单元格进行计算的单元格数,接下来$n$行,每行第一个字符串为该单元格编号,接下来若干个字符串表示该单元格引用的单元格编号。
输出格式
对于每一组测试数据,若有循环依赖,则输出$Yes$,否则输出$No$。
样例
样例输入:
3
1
AA13 AA13
3
B1 A1 A2
C1 B1 A1
A2 C1 A1
4
B1 A1
C1 B1 A1
D1 C1 B1 A1
E1 D1 C1 B1 A1
样例输出:
Yes
Yes
No
数据范围与提示
样例解释:
第一组数据中,$AA13$单元格引用自身,构成了自循环依赖。
第二组数据描述了题面中的例子。
第三组数据中,$B1$引用了$A1$,$C1$引用了$B1$和$A1$,以此类推到$E1$,每一个单元格只会引用在该单元格之前列的单元格的值,因此不会构成循环依赖。
数据范围:
对于$20\%$的数据,有$1\leqslant n\leqslant 10$。
对于$50\%$的数据,有$1\leqslant n\leqslant 100$。
对于另外$30\%$的数据,每个单元格至多引用一个单元格。
对于$100\%$的数据,有$1\leqslant n\leqslant 30,000$,单元格编号为长度不超过$10$的字符串,每个单元格都引用不超过$10$个单元格(计重数,下同),每组数据中单元格编号的数量$\leqslant 90,000$,每个测试点中单元格编号的总数量不超过$450,000$,在任意一组数据中,每行第一个单元格编号不重复,但每个单元格所引用的单元格编号可能重复。
题解
玄学读入,离散化,建图,拓扑,一遍过样例!

一脸懵逼……
发现旁边同学也都是这样额。
其实
$\rightarrow$
$=$
出题人居然用$Windows$造数据!!!
换行附在$NOILinux$下是\n而在$Windows$下是\r。
剩下的就很裸了,不过如果你想用$tarjan$判环我也不拦你。
时间复杂度:$\Theta(m)$($m$表示依赖关系数)。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
unordered_map<unsigned long long,int>mp;
struct rec{int nxt,to;}e[200001];
int head[100001],cnt;
int n;
char ch[20];
int top,tot;
int du[100001];
queue<int> q;
unsigned long long hsh[500001];
unsigned long long hd[100001];
vector<unsigned long long>son[100001];
void pre_work()
{
mp.clear();cnt=top=tot=0;
memset(head,0,sizeof(head));
memset(son,0,sizeof(son));
memset(du,0,sizeof(du));
}
unsigned long long get()
{
int len=strlen(ch+1);unsigned long long res=0;
for(int i=1;i<=len;i++)res=res*131+ch[i]-'0';
return res;
}
void add(int x,int y)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
head[x]=cnt;
}
bool topsort()
{
int res=0;
for(int i=1;i<=tot;i++)if(!du[i]){q.push(i);res++;}
while(q.size())
{
int x=q.front();q.pop();
for(int i=head[x];i;i=e[i].nxt)
{
du[e[i].to]--;
if(!du[e[i].to]){res++;q.push(e[i].to);}
}
}
return res==tot;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
pre_work();
for(int i=1;i<=n;i++)
{
scanf("%s",ch+1);
hd[i]=get();
hsh[++top]=hd[i];
char c=getchar();
while(c!='\r')
{
scanf("%s",ch+1);
hsh[++top]=get();
son[i].push_back(hsh[top]);
c=getchar();
}
}
sort(hsh+1,hsh+top+1);
for(int i=1;i<=top;i++)if(hsh[i]!=hsh[i-1])mp[hsh[i]]=++tot;
for(int i=1;i<=n;i++)
{
hd[i]=mp[hd[i]];
for(int j=0;j<son[i].size();j++)
son[i][j]=mp[son[i][j]];
}
for(int i=1;i<=n;i++)
for(int j=0;j<son[i].size();j++)
{add(son[i][j],hd[i]);du[hd[i]]++;}
puts(topsort()?"No":"Yes");
}
return 0;
}
rp++
[CSP-S模拟测试]:循环依赖(拓扑)的更多相关文章
- 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖
本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...
- Spring的循环依赖
本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...
- 面试必杀技,讲一讲Spring中的循环依赖
本系列文章: 听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configu ...
- 3.2spring源码系列----循环依赖源码分析
首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码 ...
- 3.3 Spring5源码---循环依赖过程中spring读取不完整bean的最终解决方案
根据之前解析的循环依赖的源码, 分析了一级缓存,二级缓存,三级缓存的作用以及如何解决循环依赖的. 然而在多线程的情况下, Spring在创建bean的过程中, 可能会读取到不完整的bean. 下面, ...
- 3.4 spring5源码系列--循环依赖的设计思想
前面已经写了关于三篇循环依赖的文章, 这是一个总结篇 第一篇: 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 第二篇: 3.2spring源码系列----循环依赖源 ...
- 面试阿里,腾讯,字节跳动90%都会被问到的Spring中的循环依赖
前言 Spring中的循环依赖一直是Spring中一个很重要的话题,一方面是因为源码中为了解决循环依赖做了很多处理,另外一方面是因为面试的时候,如果问到Spring中比较高阶的问题,那么循环依赖必定逃 ...
- 从一部电影史上的趣事了解 Spring 中的循环依赖问题
title: 从一部电影史上的趣事了解 Spring 中的循环依赖问题 date: 2021-03-10 updated: 2021-03-10 categories: Spring tags: Sp ...
- BFS (1)算法模板 看是否需要分层 (2)拓扑排序——检测编译时的循环依赖 制定有依赖关系的任务的执行顺序 djkstra无非是将bfs模板中的deque修改为heapq
BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not ro ...
随机推荐
- sequelize学习笔记
示例: const Sequelize = require('sequelize'); // 建立连接 const sequelize = new Sequelize('test', 'root', ...
- 打印从1到最大的n位数(考虑大数问题)
void Print1ToMaxOfNDigits(int n) { if(n <= 0) { return; } int * number = new int[n]; for(int i = ...
- python之jupyter notebook
jupyter是一种交互式计算和开发环境的笔记,ipython命令行比原生的python命令行更加友好和高效,还可以运行web版的界面,支持多语言,输出图形.音频.视频等功能. 安装 pip inst ...
- 【Git的基本操作一】文件初始化及设置签名
1. 本地库初始化 命令: git init 效果:
- ado.net 断开 非断开
非断开 SqlConnection SqlCommand / SqlDataReader 接 断开 SqlConnection SqlDataAdapter / DataSet 接
- c++编程的字符集及其转换
一.两种字符集 多字节字符集(MBCS):因为计算机最早是在英语国家诞生的,大多数英文信息是由英文字母.数字以及一些其它字符构成了一个128个字符的ASCII字符集.本来这对于英语国家来说够用了.但是 ...
- CentOS 安装 elasticsearch 注意点
注意点: 1. 从官网下载以 rpm 结尾的软件包 7.3.1版本 下载地址: https://artifacts.elastic.co/downloads/elasticsearch/elastic ...
- Linux用户组管理及用户权限2
用户.组和权限管理 Multi-tasks,Multi-Users,多任务,多用户的计算机 每个使用者: 用户标识.密码: Authentication ...
- hive-staging文件产生的原因和解决方案
通过spark-sql.hive-sql.hue等提交select或者insert overwrite等sql到hive时,会产生该目录,用于临时存放执行结果,比如insert overwrite会将 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro]
[易学易懂系列|rustlang语言|零基础|快速入门|(22)|宏Macro] 实用知识 宏Macro 我们今天来讲讲Rust中强大的宏Macro. Rust的宏macro是实现元编程的强大工具. ...