题面

每一个奶牛都喜欢自己,除此以外还有一些喜欢的对象,用边表示。
并且奶牛的喜欢符合传递关系,即A喜欢B,B喜欢C则A喜欢C
被全体奶牛喜欢的奶牛称为明星
给出N头奶牛和M个喜欢关系,求明星数量

1<=N<=10000,1<=M<=50000

分析

如果整个图只是一个强连通分量,那么显然所有点间都可相互到达(喜欢都能传递到),所以图内所有点都是明星。

考虑有多个强连通分量的情况,可以把每个强连通分量先缩点。

像这种情况,因为有F→C的边,所以分量2中的点都能到达分量1,分量1的出度为0,也就可以做到让分量1内的ABC成为明星

而如果删去F→C的边,分量1和2的出度都为0,就不可能做到某个牛成为明星,因为另一个分量的牛都不喜欢它

经过思考,最终的情况其实就是:当存在大于等于2个分量出度为0时,就不存在明星(如两个出度0的分量中取一个牛,另一个分量中的牛都不喜欢它,不满足所有牛都喜欢)
1个分量出度为0时,其余分量的喜欢可以传递给它,所以这个分量内所有牛都是明星
0个分量出度0,空图。。。就不存在了。

这是求完强连通分量之后的缩点问题,关于求强连通分量,我用的是tarjan的板子。
tarjan法求强连通分量的算法其实和求割点差不多,都用到了pre,low函数,一样的dfs。

标记分量的方法就是找到dfs中第一个进入某个分量的元素,这个元素的特点是low[u]=pre[u],在dfs过程中用一个栈存下还没有分配连通块的元素,一旦遇到了low[u]=pre[u],就连续出栈到u,这一次出栈的元素都属于同一个强连通分量。

代码

#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
vector<int> G[50004];
int dfs_clock = 0, scc_cnt = 0;//时间戳,强连通分量组编号
int sccno[10004];//表示每个点属于哪个强连通块
int pre[10004];//dfs序
int low[10004];//low[u]表示u及其后带通过反向边最多能返回到哪
stack<int> s;//存当前的节点
int out[10004];//出度统计,序号是强连通分量的编号
void dfs(int u)
{pre[u] = low[u] = ++dfs_clock;s.push(u);for (int i = 0; i < G[u].size(); i++){int v = G[u][i];//下一个if (!pre[v])//未到过v{dfs(v);low[u] = min(low[u], low[v]);}else if (!sccno[v])//有可能是新的反向边{low[u] = min(low[u], pre[v]);}}if (low[u] == pre[u])//是第一次发现这个连通分量的点{scc_cnt++;while (true){int x = s.top();s.pop();sccno[x] = scc_cnt;if (x == u)break;}}
}
void find_scc(int n)
{for (int i = 1; i <= n; i++){if (!pre[i])dfs(i);}
}
int main()
{ios::sync_with_stdio(false);int n, m,u,v;cin >> n >> m;for (int i = 0; i < m; i++){cin >> u >> v;G[u].push_back(v);}find_scc(n);//开始寻找强连通分量的函数//sccno已经处理完,1~scc_cnt//开始处理每个块的出度问题for (int i = 1; i <= n; i++){for (int j = 0;j < G[i].size();j++)//(i,G[i][j])是一条边{if (sccno[i] != sccno[G[i][j]])out[sccno[i]]++;//不是同一个块,则i的出度++}}int ans = 0;//此时记录out为0的块的个数for (int i = 1; i <= scc_cnt; i++){if (out[i] == 0)ans++;}if (ans > 1)cout << 0;//有2个及以上出度0的块,不存在明星else {ans = 0;for (int i = 1; i <= n; i++){if (out[sccno[i]] == 0)ans++;//输出出度0的块内所有点}cout << ans;}return 0;
}

求强连通分量部分参考了《算法竞赛入门经典-训练指南》的板子

洛谷P2341 强连通分量相关推荐

  1. 上白泽慧 洛谷1726 强连通分量

    题目描述 在幻想乡,上白泽慧音是以知识渊博闻名的老师.春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄.因此慧音决定换一个能够聚集最多人数的村庄作为新的教学地点.人间 ...

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

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

  3. 洛谷 P2341 - 受欢迎的牛

    题目描述 P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G 解法: 首先,明确一下什么是明星奶牛:受欢迎的牛只可能是图中唯一的出度为0的强连通分量中的所有奶牛. 为什么? 强连 ...

  4. 洛谷 P2341 [HAOI2006]受欢迎的牛

    题目 题目背景 本题测试数据已修复. 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢" ...

  5. 洛谷P2341(Tarjan+缩点)

    解题报告:对于Tarjan的之前的理解的更正: 关于low数组在同一个联通分量中并不是所有的点都是标记为该搜索树的dfn!所以用book数组充当染色的角色. 关于该题的大意就是如果存在两个或以上的明星 ...

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

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

  7. 洛谷 P2341 【HAOI2006】受欢迎的牛

    题目链接 https://www.luogu.org/problem/P2341 分析 Tarjan缩点,最后DAG中,唯一的出度为 000 的点的大小即为答案. AC代码 #include < ...

  8. 洛谷P2341 受欢迎的牛

    题目链接:https://www.luogu.org/problem/show?pid=2341 解题思路: 1.首先可以想到在一个联通块内的牛都可以成为明星奶牛(互相喜欢).这样我们就可以把它们缩成 ...

  9. 洛谷P2341(受欢迎的牛)题解

    题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢"是可以传递的--如果A喜 欢B,B喜 ...

最新文章

  1. html脱离标准文档流,关于css脱离标准文档流的两种方式
  2. 生产环境中配置的samba
  3. python 数组在最前面插入数据_Python 按照现有规则将数值插入到数组中
  4. machine learning for hacker记录(3) 贝叶斯分类器
  5. 【刷题】BZOJ 3653 谈笑风生
  6. 70打印位置调整_闵行公司做账发票打印不全该如何调整?
  7. postgresql命令行
  8. 23、jQuery九类选择器/jQuery常用Method-API/jQuery常用Event-API
  9. RTCP协议解析--RR
  10. Kafka配置4--Windows下配置Kafka的SSL证书
  11. 无向图 是什么 如何保存 如何搜索 求分组 求最短路径
  12. CAD导出.eps格式图
  13. linux minerd 进程,linux中了minerd之后的完全清理过程(详解)
  14. LaTeX 排版(三)——排版样式设定
  15. 宝塔linux 解压文件,宝塔面板能否解压缩文件
  16. 外贸网站 | 在NameCheap或NameSilo购买网站域名
  17. STM32单片机初学5-IIC通信驱动OLED屏幕
  18. pip install xx 时遇到There was a problem confirming the ssl certificate...的解决办法
  19. keep sb updated_keep you update 和keep you updated哪个正确
  20. Spring Cloud (Eureka,Feign,Hystrix整合)

热门文章

  1. java判断简体和繁体字_如何判断一个字符串是繁体编码还是简体编码?????????...
  2. 晴天霹雳。。傲盾把我的Linux格成了03系统了?之一
  3. Android 解析JSON数据
  4. 【小趴菜STM32开发笔记】---- 01输入输出端口GPIO
  5. html5的div左右布局方面问题(1)
  6. 电脑屏幕录制软件哪个好 如何使用
  7. Unity3D之MeleeWeaponTrail武器轨迹插件的使用
  8. case、循环语句(while、for、until)
  9. 深度学习——残差神经网络ResNet在分别在Keras和tensorflow框架下的应用案例
  10. python+adb实现自动刷抖音视频