[POI2005]SKA-Piggy Banks (Tarjan缩点)
2024-09-29 23:19:45
题目链接
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;
}
最新文章
- Golang 语法学习笔记
- [转]SQLite C/C++
- tachyon 本地模式安装
- 强大的桌面用 PDF 重排工具:K2pdfopt 简明教程
- 严重: A child container failed during start
- 使用控制台对Redis执行增删改查命令
- sqlmap简单使用
- 在内存中加载DLL
- POJ1487 Single-Player Games 高斯消元
- [OpenCV] Samples 16: Decompose and Analyse RGB channels
- C#:memcached安装及.NET中的Memcached.ClientLibrary使用详解
- bower 和 npm 的区别
- Unity[C#] Reflection Use
- 对Attention is all you need 的理解
- 如何设置Vmware下Linux系统全屏显示
- tp3.2分页功能
- python代码的那些设计
- WordPress 主题教程
- Android 调用系统相机拍照保存以及调用系统相册的方法
- UNITY UI字体模糊的原因