图论特辑 : Tarjan
强连通分量
相关的定义
- 强连通:我们称一个图是强连通的,当且仅当这个图的任意两个点相互可达。
- 强连通图:一张强连通的图。
- 强连通子图:一个强连通的子图。
- 强连通分量
:极大的两联同子图。
求解强连通分量 算法
对于一个点,维护两个量:
整个过程是在 dfs 中进行的,会生成一颗 dfs 生成树,所以下面的讲述中可能会牵扯到一些树的定义;
我们会制作栈,记录访问的节点,当找到一个的时候将栈弹出元素进行处理。
其中
一些显著的特征:当
的时候可以找到一个 ,顺着栈找就行了。
更加详细地,
典型应用:缩点
可以将处于相同强连通分量的点缩成一点,让原图
code
#include <bits/stdc++.h>
using std::cin;
using std::cerr;
using std::cout;
using std::queue;
#define ll long long
#define db double
#define LL __int128
#define pii pair<int,int>
#define sec second
#define fir first
#define Gc getchar
#define R() IO::read()
#define add push_back
#define W(x) write(x)
const int N=16005;
namespace IO{
int read(void){
int x=0;
char ch=0;
while(!isdigit(ch)) ch=Gc();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=Gc();
return x;
}
void write(int x){
if(x>9) write(x/10);
putchar(x%10^48);
}
}
namespace Graph{
std::vector<int> G[N],T[N];
int col[N],stack[N],dfn[N],low[N],val[N],a[N];
int f[N];
int top,tot;
int n,m,Cnt;
std::bitset<N> vis;
void Init_Input(void){
n=R(),m=R();
for(int i=1;i<=n;++i)
a[i]=R();
for(int i=1;i<=m;++i){
int ai=R(),aj=R();
G[ai].add(aj);
}
}
void Tarjan(int u){
dfn[u]=low[u]=++tot;
stack[++top]=u;
vis[u]=true;
for(int v:G[u]){
if(!dfn[v]) Tarjan(v),low[u]=std::min(low[v],low[u]);
else if(vis[v]) low[u]=std::min(low[u],dfn[v]);
} if(dfn[u]==low[u]){
++Cnt;
while(stack[top]!=u){
col[stack[top]]=Cnt;
val[Cnt]+=a[stack[top]];
vis[stack[top]]=0;
top--;
}
col[stack[top]]=Cnt;
val[Cnt]+=a[stack[top]];
vis[stack[top]]=0;
top--;
}
}
int ans=0;
void Debug(void){
for(int i=1;i<=n;++i){
printf("col [ %d ] -> %d\n",i,col[i]);
}
}
void Run(void){
Init_Input();
for(int i=1;i<=n;++i)
if(!dfn[i]) Tarjan(i);
for(int i=1;i<=n;++i){
for(int v:G[i])
if(col[i]!=col[v])
T[col[i]].add(col[v]);
}
for(int i=Cnt;i;--i){
f[i]+=val[i];
ans=std::max(ans,f[i]);
for(int v:T[i]) f[v]=std::max(f[v],f[i]);
}
}
void Output(){ IO::W(ans);putchar('\n'); }
}
int main(){ Graph::Run();Graph::Output(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人