题面

传送门:https://www.luogu.org/problemnew/show/P2341


Solution

前排提示,本蒟蒻做法既奇葩又麻烦

我们先可以把题目转换一下。

可以把一头牛喜欢另外一头牛理解为另外一头牛被一头牛喜欢。

我们把被喜欢的关系建边,即B被A喜欢,从B向A连一条有向边

显然,一个点若能到达其他所有节点,它就是题目中的明星牛。

接下来,我们可以考虑一个类似于DP的做法。

一个点能访问到的点,等同于它的儿子们访问的到的点加上它自己

显然,这种特性要在DAG(有向无环图)上才能方便的使用。

所以说,我们第一步要对题目做的是缩点。

缩完点之后,我们就可以进行图上DP了。

我们可以用一个01数组f[i][j]表示i能具体能到达的点为j(用010101数列表示)。

显然 f[i] |= f[k] (或运算)(k为i直接相连的点)

答案为f[i][j] j=11111111.... 的点

当然,这样做有一个问题。

点的最大数目为n,我们这样做是O(n^2)的,在最坏条件(没有一个点能缩在一起)的情况下,会T。

我们这时候就得请出bitset。

bitset的食用方法:https://www.cnblogs.com/RabbitHu/p/bitset.html(借用胡小兔dalao的博客)

使用bitset后,我们计算一个点能到达其他的点的复杂度一下子降为了O(n/32)

总复杂度为O(n^2/32) 

然后就可以过啦。


Code

//Luogu P2341 [HAOI2006]受欢迎的牛
//June,5th,2018
//缩点+(完全没必要的)bitset
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<bitset>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=10000+100;
vector <int> e[N],e2[N];
int n,m,belong[N],nd_tot,dfn[N],mcount,low[N],cnt[N];
bool InStack[N];
stack <int> s;
bitset <N> arrival[N];
void Tarjan(int now)
{
InStack[now]=true;
s.push(now);
dfn[now]=low[now]=++mcount;
for(int i=0;i<int(e[now].size());i++)
if(dfn[e[now][i]]==0)
{
Tarjan(e[now][i]);
low[now]=min(low[now],low[e[now][i]]);
}
else if(InStack[e[now][i]]==true)
low[now]=min(low[now],low[e[now][i]]);
if(low[now]==dfn[now])
{
nd_tot++;
while(s.empty()==false)
{
int temp=s.top();
s.pop();
InStack[temp]=false;
belong[temp]=nd_tot;
cnt[nd_tot]++;
if(temp==now) break;
}
arrival[nd_tot][nd_tot]=true;
}
}
bool vis[N];
int ans=0;
void dfs(int now)
{
vis[now]=true;
for(int i=0;i<int(e2[now].size());i++)
{
if(vis[e2[now][i]]==false)
dfs(e2[now][i]);
arrival[now]|=arrival[e2[now][i]];
}
if(int(arrival[now].count())==nd_tot)
ans+=cnt[now];
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
e2[i].reserve(4),
e[i].reserve(4);
for(int i=1;i<=m;i++)
{
int s=read(),t=read();
e[t].push_back(s);
} for(int i=1;i<=n;i++)
if(dfn[i]==0)
Tarjan(i);
for(int i=1;i<=n;i++)
for(int j=0;j<int(e[i].size());j++)
if(belong[i]!=belong[e[i][j]])
e2[belong[i]].push_back(belong[e[i][j]]);
for(int i=1;i<=nd_tot;i++)
if(vis[i]==false)
dfs(i); printf("%d",ans);
return 0;
}

正解(C++)

[Luogu P2341] [HAOI2006]受欢迎的牛 (缩点+bitset)的更多相关文章

  1. Luogu P2341 [HAOI2006]受欢迎的牛 SCC缩点

    把强连通分量缩点,如果有且仅有一个出度为0的强连通分量,那么答案就是他的size:如果有多个入度为0的,那么没有明星牛. #include<cstdio> #include<iost ...

  2. 【luogu P2341 [HAOI2006]受欢迎的牛】 题解

    题解报告:https://www.luogu.org/problemnew/show/P2341 我们把图中的强连通分量缩点,然后只有出度为0的牛是受欢迎的,这样如果出度为0的牛只有一个,说明受所有牛 ...

  3. Luogu P2341 [HAOI2006]受欢迎的牛

    这道题应该也是经典的SCC题了吧 印象中不知道在在班里上课的时候在紫书,ACM竞赛的那些书上看到多少次(有点奇怪) 首先思路很明显,就是要找出有多少个点,以它们为起点可以遍历整个图 首先考虑一种情况, ...

  4. 洛谷P2341 [HAOI2006]受欢迎的牛 (Tarjan,SCC缩点)

    P2341 [HAOI2006]受欢迎的牛|[模板]强连通分量 https://www.luogu.org/problem/P2341 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就 ...

  5. P2341 [HAOI2006]受欢迎的牛(tarjan+缩点)

    P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的 ...

  6. 【模板】Tarjan缩点,强连通分量 洛谷P2341 [HAOI2006]受欢迎的牛 [2017年6月计划 强连通分量01]

    P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的 ...

  7. 洛谷 P2341 [HAOI2006]受欢迎的牛 解题报告

    P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢&q ...

  8. [Luogu 2341] HAOI2006 受欢迎的牛

    [Luogu 2341] HAOI2006 受欢迎的牛 智能推的水题,一看是省选题就给做了,做一半才发现 Tarjan 算法忘干净了. Tarjan 求出SCC,算出每一个 SCC 包含原图的点数(s ...

  9. 洛谷——P2341 [HAOI2006]受欢迎的牛//POJ2186:Popular Cows

    P2341 [HAOI2006]受欢迎的牛/POJ2186:Popular Cows 题目背景 本题测试数据已修复. 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所 ...

随机推荐

  1. 零基础学习Kmeans聚类算法的原理与实现过程

    内容导入: 聚类是无监督学习的典型例子,聚类也能为企业运营中也发挥者巨大的作用,比如我们可以利用聚类对目标用户进行群体分类,把目标群体划分成几个具有明显特征区别的细分群体,从而可以在运营活动中为这些细 ...

  2. 卧槽!最新编程语言排名,Java 沦为老二。。

    2020 年 9 月刚过去,栈长看了下最新的 tiobe 编程语言榜,牛逼啊,C 语言居然登顶了,Java 下降 3 个点,沦为老二的位置. 数据来源TIOBE: https://www.tiobe. ...

  3. KEIL查看ARM-Cortex M架构soc的内核寄存器之 MSP

       参考下图stm32l475的参考手册: MSP指向地址基地址为0x20000000的内存处.参考STM32L475的memory map可知MSP指向的是SRAM的一块地址.并且由上面的编译信息 ...

  4. 【数量技术宅|金融数据分析系列分享】为什么中证500(IC)是最适合长期做多的指数

    更多精彩内容,欢迎关注公众号:数量技术宅.探讨数据分析.量化投资问题,请加技术宅微信:sljsz01 投资股票指数相比个股的优势 我们在投资股票的时候,如果持仓集中在一只或者有限几只股票上,恰好不幸遇 ...

  5. Gearman实战第一弹:异步处理结算单

    昨天梦回jm,醒来之后看着窗外万里晴空,想大声喊一句:爷青回! 我想起之前使用gearman的岁月.不知不觉也过了快5年,想总结一篇关于gearman的技术文章算是一种对青春的祭奠,再不写的话更少有p ...

  6. Springboot应用使用Docker部署

    首先准备好springboot应用,然后打包,我这里已经准备好了一个jar包 然后上传到服务器,准备一个目录用于存放jar包和Dokerfile文件 编写Dokerfile文件 我这里写的很简单,就简 ...

  7. 99%的Android开发不得不面对的三道坎,到底该怎么破?

    今年比往年要特殊一些,受疫情的影响,很多公司都出现了裁员现象.以至于最近很多技术同学也在纷纷向我倒苦水. 王鹏便是其中的一员,王鹏之前是在一线城市的一家小型互联网公司做Android应用开发.从毕业实 ...

  8. day14 Pyhton学习

    一.迭代器-概念 可迭代协议:内部含有__iter__方法的值/变量都是可迭代的 如何得到一个迭代器:可迭代变量.__iter__()返回一个迭代器 迭代器协议:内部含有__iter__方法和__ne ...

  9. 灵魂拷问:你真的理解System.out.println()执行原理吗?

    原创/朱季谦 灵魂拷问,这位独秀同学,你会这道题吗?  请说说,"System.out.println()"原理...... 这应该是刚开始学习Java时用到最多一段代码,迄今为止 ...

  10. centos8平台使用ip命令代替ifconfig管理网络

    一,为什么建议使用ip命令代替ifconfig? 1,ifconfig所属的net-tools包已经不再被维护了 虽然可以用,但会发生看不到部分ip等情况, [root@centos8 liuhong ...