(拓扑排序+bitset)吉林大学ACM集训队选拔赛(重现赛)C Strange Bulbs

 这题一开始看的时候,肯定是要拓扑的,但是有一个问题,一个点的开关,会影响它所有的子节点,一个点的是否要开关,又是这所有影响到这点的父节点数量和的奇偶决定的,比方说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();
}

猜你喜欢

转载自blog.csdn.net/qq_43497140/article/details/106744542
今日推荐