题目传送门(内部题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模拟测试]:循环依赖(拓扑)的更多相关文章

  1. 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

    本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...

  2. Spring的循环依赖

    本文简要介绍了循环依赖以及Spring解决循环依赖的过程 一.定义 循环依赖是指对象之间的循环依赖,即2个或以上的对象互相持有对方,最终形成闭环.这里的对象特指单例对象. 二.表现形式 对象之间的循环 ...

  3. 面试必杀技,讲一讲Spring中的循环依赖

    本系列文章: 听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configu ...

  4. 3.2spring源码系列----循环依赖源码分析

    首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码 ...

  5. 3.3 Spring5源码---循环依赖过程中spring读取不完整bean的最终解决方案

    根据之前解析的循环依赖的源码, 分析了一级缓存,二级缓存,三级缓存的作用以及如何解决循环依赖的. 然而在多线程的情况下, Spring在创建bean的过程中, 可能会读取到不完整的bean. 下面, ...

  6. 3.4 spring5源码系列--循环依赖的设计思想

    前面已经写了关于三篇循环依赖的文章, 这是一个总结篇 第一篇: 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 第二篇: 3.2spring源码系列----循环依赖源 ...

  7. 面试阿里,腾讯,字节跳动90%都会被问到的Spring中的循环依赖

    前言 Spring中的循环依赖一直是Spring中一个很重要的话题,一方面是因为源码中为了解决循环依赖做了很多处理,另外一方面是因为面试的时候,如果问到Spring中比较高阶的问题,那么循环依赖必定逃 ...

  8. 从一部电影史上的趣事了解 Spring 中的循环依赖问题

    title: 从一部电影史上的趣事了解 Spring 中的循环依赖问题 date: 2021-03-10 updated: 2021-03-10 categories: Spring tags: Sp ...

  9. BFS (1)算法模板 看是否需要分层 (2)拓扑排序——检测编译时的循环依赖 制定有依赖关系的任务的执行顺序 djkstra无非是将bfs模板中的deque修改为heapq

    BFS模板,记住这5个: (1)针对树的BFS 1.1 无需分层遍历 from collections import deque def levelOrderTree(root): if not ro ...

随机推荐

  1. c#连接Java后台,处理返回的数据

    首先定义共通文件,根据url连接Java后台 class ConntectUtil { public JObject ConsoleApplication(string appID, CustomDa ...

  2. 移动站Web开发图片自适应两种常见情况解决方案

    本文主要说的是Web中图片根据手机屏幕大小自适应居中显示,图片自适应两种常见情况解决方案.开始吧 在做配合手机客户端的Web wap页面时,发现文章对图片显示的需求有两种特别重要的情况,一是对于图集, ...

  3. O056、Extend Volume 操作

    参考https://www.cnblogs.com/CloudMan6/p/5645305.html   今天学习如何扩大volume的容量,为了保护现有的数据,cinder不允许缩小volume. ...

  4. selenium:能够模拟人类打开浏览器的爬虫利器

    介绍 selenium相当于是一个机器人,可以模拟人类登陆浏览器的行为,比如点击.填充数据.删除cookie等等.Chromedriver是一个驱动Chrome的程序,使用它才可以驱动浏览器,其实Ch ...

  5. 《Linux就该这么学》day3

    ps:原谅我的书法出自鲁迅的<野草> <Linux就该这么学>书本介绍: 本书是由全国多名红帽架构师(RHCA)基于最新Linux系统共同编写的高质量Linux技术自学教程,极 ...

  6. 基于docker安装pxc集群

    基于docker安装pxc集群 一.PXC 集群的安装 PXC集群比较特殊,需要安装在 linux 或 Docker 之上.这里使用 Docker进行安装! Docker的镜像仓库中包含了 PXC数据 ...

  7. IPC之ipc_sysctl.c源码解读

    // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2007 * * Author: Eric Biederman <ebie ...

  8. C++——函数

    C++基础函数 (一)函数的参数传递 在没有调用函数之前,函数的形参并没有占据实际的空间. 1.值传递 传入的仅仅只是一个值--就是把实参的值赋给形参.形参自己会在内存中开辟一个空间! 2.传引用 这 ...

  9. 生产者消费者问题--BlockingQueue

    # 代码: public class App { public static void main(String[] args) { BlockingQueue<Integer> queue ...

  10. 博弈论BOSS

    基础博弈的小结:http://blog.csdn.net/acm_cxlove/article/details/7854530 经典翻硬币游戏小结:http://blog.csdn.net/acm_c ...