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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!