tarjan模板

信息传递

题目描述

tarjan模板

void tarjan(int x)
{
dfn[x]=low[x]=++num;
stk.push(x);
v[x]=1;
for(int i=h[x];i;i=nxt[i])
{
if(!dfn[to[i]])
{
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}
else if(v[to[i]])
{
low[x]=min(low[x],dfn[to[i]]);
}
}
if(low[x]==dfn[x])
{
sum=0;
int y;
++t;
do
{
y=stk.top();
stk.pop();
v[y]=0;
belong[y]=t;
sum++;
} while(y!=x);
if(sum>1) ans=min(ans,sum);
}
}

本题要求求出最大强连通分量最小值(当然1不算)
所以当sum<2时跳过
还有一个地方就是本题没说所有点都是联通的,所以要循环一遍所有点
如果这个点的dfn值为零,说明这个点和之前搜过的点不在一个图中
最后上代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int maxm=4e5+10;
int n,tot,num,t,ans=0x3f3f3f3f,belong[maxn],sum;
int h[maxn],nxt[maxm],to[maxm],dfn[maxn],v[maxn],low[maxn];
stack<int> stk;
void addedge(int x,int y)
{
to[++tot]=y;
nxt[tot]=h[x];
h[x]=tot;
}
void tarjan(int x)
{
dfn[x]=low[x]=++num;
stk.push(x);
v[x]=1;
for(int i=h[x];i;i=nxt[i])
{
if(!dfn[to[i]])
{
tarjan(to[i]);
low[x]=min(low[x],low[to[i]]);
}
else if(v[to[i]])
{
low[x]=min(low[x],dfn[to[i]]);
}
}
if(low[x]==dfn[x])
{
sum=0;
int y;
++t;//记录强连通分量个数
do
{
y=stk.top();
stk.pop();
v[y]=0;
belong[y]=t;//存y点属于哪个强连通分量
sum++;
} while(y!=x);
if(sum>1) ans=min(ans,sum);//如果是单点构成强连通分量就忽略
}
}
int main()
{
scanf("%d",&n);
int a;
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
addedge(i,a);//建图
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]) tarjan(i);//循环防止有多个图
}
printf("%d",ans);
return 0;
}
posted @   晨曦ccx  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示