Luogu P4957 [COCI2017-2018#6] Alkemija
题意
有 \(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的更多相关文章
- COCI2017/2018 CONTEST #7
Prosjek 显然,越大的数应该越后参与平均数的计算,这样受较小数的影响就小一些 那我们就排个序,贪心的从最小的数开始往大的计算平均数即可 时间复杂度\(O(nlogn)\) Timovi 把分组分 ...
- 解题报告:luogu P5020(NOIP 2018 D1T2)
题目链接:P5020 货币系统 \(NOIP\) 的题挺精华啊. 开始感觉自己有隐约的思路,但感觉太暴力,连数据范围都没看,就去看题解了(不会啊). 听说是\(dp\)又是一惊,直接弃疗. 其实只是个 ...
- Noip-pj2018游记
2019/1/3 搬运于我的luogu博客 2018/10/9 没有去试机,在学校搞文化课去了.准考证是让学校的信息课老师帮我拿的 回家后随手A了P1198 P3870 P2846 P1531 感觉真 ...
- [luogu] P4364 [九省联考2018]IIIDX(贪心)
P4364 [九省联考2018]IIIDX 题目背景 Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI ...
- luogu P4365 [九省联考2018]秘密袭击coat
luogu 这里不妨考虑每个点的贡献,即求出每个点在多少个联通块中为第\(k\)大的(这里权值相同的可以按任意顺序排大小),然后答案为所有点权值\(*\)上面求的东西之和 把比这个点大的点看成\(1\ ...
- luogu P4382 [九省联考2018]劈配
luogu 我记得我第一次做这道题的时候屁都不会qwq 先考虑第一问,暴力是依次枚举每个人,然后从高到低枚举志愿,枚举导师,能选就选.但是可以发现前面的人选的导师可能会导致后面的人本来可以选到这个志愿 ...
- luogu P4363 [九省联考2018]一双木棋chess
传送门 对抗搜索都不会,我真是菜死了qwq 首先根据题目条件,可以发现从上到下每一行的棋子数是单调不增的,然后n m都比较小,如果把状态搜出来,可以发现合法状态并不多,所以可以用一个11进制数表示状态 ...
- Luogu 2018 秋令营 Test 2
T1: 题目描述 你正在使用过时的浏览器,洛谷暂不支持. 请 升级浏览器 以获得更好的体验! Bob 来到了一个 $n \times m$ 的网格中,网格里有 $k$ 个豆子,第 $i$ 个豆子位于 ...
- 【题解】Luogu P4363 [九省联考2018]一双木棋chess
原题传送门 这道题珂以轮廓线dp解决 经过推导,我们珂以发现下一行的棋子比上一行的棋子少(或等于),而且每一行中的棋子都是从左向右依次排列(从头开始,中间没有空隙) 所以每下完一步棋,棋盘的一部分是有 ...
随机推荐
- 吴恩达Machine Learning学习笔记(三)--逻辑回归+正则化
分类任务 原始方法:通过将线性回归的输出映射到0-1,设定阈值来实现分类任务 改进方法:原始方法的效果在实际应用中表现不好,因为分类任务通常不是线性函数,因此提出了逻辑回归 逻辑回归 假设表示--引入 ...
- 30种SQL语句优化
1.'对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用 ...
- Java递归算法经典实例(兔子问题、阶乘、1到100累加)
https://blog.csdn.net/isitman/article/details/61199070
- NoActionBar主题下如何添加OptionsMenu
菜单无法显示 为了不显示标题栏,所以主题使用了 NoActionBar,这也直接导致选项菜单无处显示 解决方案 添加一个ToolBar,自定义标题栏 <androidx.appcompat.wi ...
- 腾讯一面!说说ArrayList的遍历foreach与iterator时remove的区别,我一脸懵逼
本文基于JDK-8u261源码分析 1 简介 ArrayList作为最基础的集合类,其底层是使用一个动态数组来实现的,这里"动态"的意思是可以动态扩容(虽然ArrayList可 ...
- .NetCore.RazorPages 获取访客的公网IP与局域网IP
dotnet.core 获取访客的公网IP与局域网IP 现在奉上代码 public void OnGet() {var ip = Content(HttpContext.Connection.Remo ...
- 【小白学PyTorch】21 Keras的API详解(上)卷积、激活、初始化、正则
[新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑答疑解惑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx6450 ...
- Oracle 按不同时间分组统计
1.按年 select to_char(record_date,'yyyy'), sum(col_8) as total_money from table_name where group by to ...
- Windows7 组策略错误:“未能打开这台计算机上的组策略对象。您可能没有合适的权限。”
在 Windows 7 系统下,打开组策略时,出现 组策略错误 -- "未能打开这台计算机上的组策略对象.您可能没有合适的权限.".如下图所示: 解决方案: 1.进入"计 ...
- 从Linux源码看Socket(TCP)的bind
从Linux源码看Socket(TCP)的bind 前言 笔者一直觉得如果能知道从应用到框架再到操作系统的每一处代码,是一件Exciting的事情. 今天笔者就来从Linux源码的角度看下Server ...