题目链接

Solution

\(Tarjan\) 缩点乱搞.

考虑到环内如果有一个被打开,那么也就全部打开了.

然后很显然入度为 \(0\) 的点需要被砸破.

所以缩点之后找到入度为 \(0\) 的即可.

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000008;
struct sj{int to,next;}a[maxn];
int head[maxn],size;
int dfn[maxn],low[maxn];
int sta[maxn],top,belong[maxn];
int cnt,tot,v[maxn],n;
int du[maxn],ans;
void add(int x,int y)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
} void tarjan(int x)
{
dfn[x]=low[x]=++tot;
sta[++top]=x;
v[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!dfn[tt]){
tarjan(tt);
low[x]=min(low[x],low[tt]);
}
else if(v[tt]) low[x]=min(low[x],dfn[tt]);
}
if(dfn[x]==low[x])
{
belong[x]=++cnt;
v[x]=0;
do{
belong[sta[top]]=cnt;
v[sta[top]]=0;
}while(sta[top--]!=x);
}
} int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x);
add(x,i);
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int x=1;x<=n;x++)
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(belong[tt]!=belong[x])
du[belong[tt]]++;
}
for(int i=1;i<=cnt;i++)
if(!du[i])
ans++;
cout<<ans<<endl;
}

最新文章

  1. Golang 语法学习笔记
  2. [转]SQLite C/C++
  3. tachyon 本地模式安装
  4. 强大的桌面用 PDF 重排工具:K2pdfopt 简明教程
  5. 严重: A child container failed during start
  6. 使用控制台对Redis执行增删改查命令
  7. sqlmap简单使用
  8. 在内存中加载DLL
  9. POJ1487 Single-Player Games 高斯消元
  10. [OpenCV] Samples 16: Decompose and Analyse RGB channels
  11. C#:memcached安装及.NET中的Memcached.ClientLibrary使用详解
  12. bower 和 npm 的区别
  13. Unity[C#] Reflection Use
  14. 对Attention is all you need 的理解
  15. 如何设置Vmware下Linux系统全屏显示
  16. tp3.2分页功能
  17. python代码的那些设计
  18. WordPress 主题教程
  19. Android 调用系统相机拍照保存以及调用系统相册的方法
  20. UNITY UI字体模糊的原因

热门文章

  1. mysql命令行导出导入,附加数据库
  2. Apache超时配置
  3. iOS开发之WIFI,3G/4G两种网络同时使用技巧
  4. Codeforces 517 #A
  5. pandas中数据聚合【重点】
  6. centOS下lnamp安装
  7. 小程序电脑调试没有问题,真机预览报错fail hand shake error
  8. python网络-Socket之TCP编程(26)
  9. Java-basic-7-面向对象
  10. ACM训练联盟周赛 A. Teemo&#39;s bad day