题意

有 \(n\) 种已知物质,现在手上有 \(m\) 种,每种无限多个。已知 \(k\) 种反应,每种可以将一些反应物变成一些生成物。求经过这些反应过后最多可以有多少种不同的物质。

\(\texttt{Data Range:}1\leq m\leq n\leq 10^5,1\leq k\leq 10^5\)

题解

由于考场上不会写各种暴力所以来练习一下如何写优雅的暴力。

首先注意到如果所有反应都是化合或分解的话就是建个图 DFS 一下就好了,但是有多变多的就不好做。

但是我们要有梦想。有一个非常暴力的方法是不断进行 \(1\sim n\) 的所有反应,如果在一轮所有反应进行过后并不能使得物质种类数增加那么就认为我们得出了答案。

这个东西效率比较低下,于是考虑怎么优化。注意到如果已经进行了某个反应的话那么以后就再也不用进行了,因为再做还是只能得到那些生成物,相当于没用,所以一个反应最多进行一次。

不仅如此,这里还有第二个优化:考虑记录一下每个物质能参加哪些反应,这样当取出一个生成物的时候就能很快的知道这个物质可以参加哪些反应而不是 \(O(k)\) 去找。

这里还有一个优化,配合第二个优化能跑得很快,就是可以不需要直接记录每个反应需要哪些物质,而是记录要完成这个反应还需要多少种物质,因为有第二个优化所以取出生成物的时候可以直接减 \(1\),如果这个反应不需要物质的话那么就一定可以反应了。

最后,这 \(k\) 个反应的依赖顺序组成了一个 DAG,所以可以用拓扑排序的思路来更新这些反应,于是就做完了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51;
queue<ll>q;
vector<ll>re[MAXN],g[MAXN];
ll n,m,kk,x,top,res;
ll vis[MAXN],visr[MAXN],l[MAXN],r[MAXN],need[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
int main()
{
n=read(),m=read();
for(register int i=1;i<=m;i++)
{
vis[read()]=1;
}
kk=read();
for(register int i=1;i<=kk;i++)
{
l[i]=read(),r[i]=read();
for(register int j=1;j<=l[i];j++)
{
!vis[x=read()]?re[x].push_back(i),need[i]++:1;
}
for(register int j=1;j<=r[i];j++)
{
g[i].push_back(read());
}
!need[i]?q.push(i),visr[i]=1:1;
}
while(!q.empty())
{
top=q.front(),q.pop();
for(register int i:g[top])
{
if(vis[i])
{
continue;
}
vis[i]=1;
for(register int j:re[i])
{
!visr[j]&&!(--need[j])?q.push(j),visr[j]=1:1;
}
}
}
for(register int i=1;i<=n;i++)
{
res+=vis[i];
}
printf("%d\n",res);
for(register int i=1;i<=n;i++)
{
vis[i]?printf("%d ",i):1;
}
}

Luogu P4957 [COCI2017-2018#6] Alkemija的更多相关文章

  1. COCI2017/2018 CONTEST #7

    Prosjek 显然,越大的数应该越后参与平均数的计算,这样受较小数的影响就小一些 那我们就排个序,贪心的从最小的数开始往大的计算平均数即可 时间复杂度\(O(nlogn)\) Timovi 把分组分 ...

  2. 解题报告:luogu P5020(NOIP 2018 D1T2)

    题目链接:P5020 货币系统 \(NOIP\) 的题挺精华啊. 开始感觉自己有隐约的思路,但感觉太暴力,连数据范围都没看,就去看题解了(不会啊). 听说是\(dp\)又是一惊,直接弃疗. 其实只是个 ...

  3. Noip-pj2018游记

    2019/1/3 搬运于我的luogu博客 2018/10/9 没有去试机,在学校搞文化课去了.准考证是让学校的信息课老师帮我拿的 回家后随手A了P1198 P3870 P2846 P1531 感觉真 ...

  4. [luogu] P4364 [九省联考2018]IIIDX(贪心)

    P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...

  5. luogu P4365 [九省联考2018]秘密袭击coat

    luogu 这里不妨考虑每个点的贡献,即求出每个点在多少个联通块中为第\(k\)大的(这里权值相同的可以按任意顺序排大小),然后答案为所有点权值\(*\)上面求的东西之和 把比这个点大的点看成\(1\ ...

  6. luogu P4382 [九省联考2018]劈配

    luogu 我记得我第一次做这道题的时候屁都不会qwq 先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿 ...

  7. luogu P4363 [九省联考2018]一双木棋chess

    传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...

  8. Luogu 2018 秋令营 Test 2

    T1: 题目描述 你正在使用过时的浏览器,洛谷暂不支持. 请 升级浏览器 以获得更好的体验! Bob 来到了一个 $n \times m$ 的网格中,网格里有 $k$ 个豆子,第 $i$ 个豆子位于 ...

  9. 【题解】Luogu P4363 [九省联考2018]一双木棋chess

    原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...

随机推荐

  1. echarts配置进度池

    近日,使用dataV中的配置,完成了进度池图表,但是有有一个缺点,就是官方没有动画方面的配置.如下图: 为了给这个进度池添加动画效果,我反向的在进度池上面铺一层由一格一格与进度池中相同的块状组成的与背 ...

  2. AA.Dapper升级了

    AA.Dapper基于dapper进一步封装而成的orm框架,提供增删改查.分页.事务.原生sql的功能,以满足日常的业务开发. 1.Repository层: DapperRepository类包含大 ...

  3. JavaScript事件对象属性e.target和this的区别

    前言: Event对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象eve ...

  4. BeetleX之webapi使用入门

    BeetleX是TCP通讯应用组件,在它之上可以扩展任何基于TCP的应用通讯功能.FastHttpApi是组件扩展的一个Http/Https/Websocket服务组件,它提供的功能丰富,包括功能有: ...

  5. 搭建单机版的kafka

    搭建单机版的kafka  

  6. npm npx cnpm yarn 的区别

    npm npm 是 Node.js 官方提供的包管理工具.用于 Node.js 包的发布.传播.依赖控制.npm 提供了命令行工具,使你可以方便地下载.安装.升级.删除包,也可以让你作为开发者发布并维 ...

  7. git克隆指定分支到本地

    我们每次使用命令 git clone https://xxx.com/android-app.git 默认 clone 的是这个仓库的 master 分支. 使用Git下载指定分支命令为:git cl ...

  8. python的PEP8代码规范

    一.缩进:每级缩进用4个空格.如果缩进不正确或缩进格式不统一,一般错误信息会明确告诉你,但有时也会出现invalid syntax报错.所谓缩进不正确,python的缩进是四个空格或一个TAB,如果缩 ...

  9. 如何从0到1的构建一款Java数据生成器-第一章

    前提 某天晚上老夫在神游时,想起白天公司同事说起的问题,这老表抱怨使用mysql生成大批的随机测试数据太过麻烦,问大家有没有好的工具推荐,老夫对这种事情当然不关心,毕竟我也不知道. 秉承着不懂就要问, ...

  10. day18 Pyhton学习 内置函数最后七个

    1. enumerate  枚举函数 for i in enumerate(['a','b','c'],1): print(i)#(1, 'a')(2, 'b')(3, 'c') goods_lst= ...