这题一开始看的时候,肯定是要拓扑的,但是有一个问题,一个点的开关,会影响它所有的子节点,一个点的是否要开关,又是这所有影响到这点的父节点数量和的奇偶决定的,比方说1到2,1到3, 2到4, 3到4,如果直接纪录每个点父节点(包括自己)有多少开关了,那a[1]=1,a[2]=2,a[3]=2,那势必会使a[4]=a[2]+a[3]=4,这就错误了,应为1的影响被重复加了
就如下图
所以不能这么简单的加,而要纪录4这个点是具体被哪些点影响了,但我们又不能暴力遍历,所以一个更好点办法是bitset纪录每个点的状态,从1开始,按拓扑序遍历,子节点或上父亲节点的状态,然后如果1的数量为奇,就说明自己要进行一次开关,然后把b[i][i]=1
(点旁边的数是该点纪录哪些父亲节点受到了影响,边上的数是他这个点传递给子节点的影响)
链接:https://ac.nowcoder.com/acm/contest/5944/C
来源:牛客网
Christmas is coming. XiaoYang has got a big Christmas tree, and he wants to decorate it.
XiaoYang loves Shiny things. He set up a net of light bulbs on the tree. n light bulbs are connected by m wires. But the bulbs and wires are strange. Each bulb has a switch. If the switch is turned, some bulbs connecting this one will also be switched. The switch operation only flows from the left end to the right end. More precisely, a wire connects u and v so that when the switch of u is turned, the switch of v is turned also. Note that a switch will be turned only once in one step.
Now only the bulb 1 is on. How many steps does it take to turn off all the bulbs?
输入描述:
The first line contains two integers n and m (1≤n≤4⋅104,n−1≤m≤8⋅104)m ~ (1 \leq n \leq 4 \cdot 10^4, n-1 \leq m \leq 8 \cdot 10^4)m (1≤n≤4⋅104,n−1≤m≤8⋅104) -- the number of bulbs and wires in the net.
Each of the next m lines contains two space-separated integers u and v (1≤u,v≤n)v ~ (1 \leq u, v \leq n)v (1≤u,v≤n) that mean there's a directed wire connecting the left u and the right v. It's guaranteed that the net is connected, acyclic and doesn't contain any self-loops or multiple edges.
#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<bitset>
using namespace std;
#define ll long long
#define inf 1e9
#define maxn 101005
vector<int>e[maxn];
int vis[maxn],d[maxn],a[maxn];
queue<int>q;
bitset<45000>b[maxn];
void bfs()
{
q.push(1);
b[1][1]=1;int ans=0;
while(!q.empty())
{
int u=q.front();
q.pop();
if(b[u].count()%2==1)
{
ans++;b[u][u]=1;
}
for(int v:e[u])
{
b[v]|=b[u];
d[v]--;
if(d[v]==0) q.push(v);
}
}
printf("%d\n",ans);
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
d[v]++;
e[u].push_back(v);
}
bfs();
}