牛客 - Strange Bulbs(bitset优化拓扑)
Posted Frozen_Guardian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客 - Strange Bulbs(bitset优化拓扑)相关的知识,希望对你有一定的参考价值。
题目链接:点击查看
题目大意:给出一张 n 个点和 m 条边组成的有向无环图,每个节点都有一个开关和一个灯泡,初始时节点 1 的灯泡是亮的,每次操作开关可以将当前灯泡的状态置反,且会对子节点的开关产生连锁反应,问至少需要操作多少次才能将所有的灯泡关上
题目分析:看到有向无环图首先想到拓扑,但是如果暴力拓扑转移每个点的状态的话,时间复杂度是 n * n 级别的,必定会超时,但是看到数据范围其实有经验的同学就会想到利用 bitset 优化了,可以优化掉 64 层的时空复杂度,经过优化后的时空复杂度就可以暴力转移了,令每个节点都维护一个 bitset 变量,记录一下前面有哪些节点会影响到该节点,如果有奇数个节点影响到了该节点的话,因为每个灯泡初始时都是灭着的,所以需要利用一次操作将其关闭,如果是偶数个则直接跳过即可,每次利用位运算向下传递状态就好了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=4e4+100;
bitset<N>b[N];
vector<int>node[N];
int du[N],n,m;
int topo()
int ans=0;
queue<int>q;
q.push(1);
b[1][1]=1;
while(q.size())
int u=q.front();
q.pop();
if(b[u].count()&1)
b[u][u]=1;
ans++;
for(auto v:node[u])
b[v]|=b[u];
if(--du[v]==0)
q.push(v);
return ans;
int main()
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
scanf("%d%d",&n,&m);
while(m--)
int u,v;
scanf("%d%d",&u,&v);
node[u].push_back(v);
du[v]++;
printf("%d\\n",topo());
return 0;
以上是关于牛客 - Strange Bulbs(bitset优化拓扑)的主要内容,如果未能解决你的问题,请参考以下文章
2021牛客暑期多校训练营8 F.Robots 离线分治+bitset