博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Luogu 2341] HAOI2006 受欢迎的牛
阅读量:4607 次
发布时间:2019-06-09

本文共 1678 字,大约阅读时间需要 5 分钟。

[Luogu 2341] HAOI2006 受欢迎的牛


智能推的水题,一看是省选题就给做了,做一半才发现 Tarjan 算法忘干净了。

Tarjan 求出SCC,算出每一个 SCC 包含原图的点数(size)以及新图上的出度(out)

并不用建图,Tarjan 时记一下 SCC 编号和 size,缩点时记录 out 就好了。

若存在唯一出度为 \(0\) 的 SCC,则这个 SCC 中所有的牛都是明星,即明星数量为这个 SCC 的 out。

否则答案为 \(0\)

#include 
#include
#include
using std::min;using std::stack;const int MAXN=10010,MAXM=50010;bool exist[MAXN];int n,m,cnt,num,sum,head[MAXN],DFN[MAXN],low[MAXN],SCC[MAXN],size[MAXN],out[MAXN];stack
st;struct edge{ int nxt,to; edge(int nxt=0,int to=0):nxt(nxt),to(to){}}e[MAXM];void AddEdge(int u,int v){ e[++cnt]=edge(head[u],v),head[u]=cnt;}void Tarjan(int u){ st.push(u),exist[u]=1,DFN[u]=low[u]=++num; for(int i=head[u],v;i;i=e[i].nxt) if(!DFN[v=e[i].to]) Tarjan(v),low[u]=min(low[u],low[v]); else if(exist[v]) low[u]=min(low[u],DFN[v]); if(DFN[u]==low[u]) { ++sum; for(int t;u!=t;) exist[t=st.top()]=0,st.pop(),++size[SCC[t]=sum]; }}void Shrink(void){ for(int u=1;u<=n;++u) for(int i=head[u],v;i;i=e[i].nxt) if(SCC[u]^SCC[v=e[i].to]) ++out[SCC[u]];}int Ans(void){ int ans=0; for(int i=1;i<=sum;++i) if(!out[i]) if(ans) return 0; else ans=size[i]; return ans;}int main(int argc,char *argv[]){ scanf("%d %d",&n,&m); for(int i=1,u,v;i<=m;++i) { scanf("%d %d",&u,&v); AddEdge(u,v); } for(int i=1;i<=n;++i) if(!DFN[i]) Tarjan(i); Shrink(); printf("%d\n",Ans()); return 0;}

谢谢阅读。

转载于:https://www.cnblogs.com/Capella/p/8568788.html

你可能感兴趣的文章
02.制作一个自己的 Java 编辑器
查看>>
03JavaScript程序设计修炼之道_2019-06-18_21-41-56_事件onfocus
查看>>
理解Twsited异步网络框架
查看>>
1217=蟠桃记
查看>>
剑指Offer:面试题25
查看>>
机器学习库--dlib
查看>>
路人甲的主角梦
查看>>
Oracle基础 06 控制文件 controlfile
查看>>
C# DateTime显示时间格式的使用
查看>>
log4net日志组件
查看>>
jquery图片过滤归类应用
查看>>
断点续传JAVA实现
查看>>
Jenkins插件之Publish Over SSH/CIFS/FTP
查看>>
寻找OEP
查看>>
TableView下拉cell
查看>>
面试题:升高的温度
查看>>
Android学习-使用单例模式实现一键退出APP
查看>>
Android-L-Samples
查看>>
判断特征中是否含有空值、空值填充
查看>>
onInterceptTouchEvent和onTouchEvent调用时序
查看>>