视频讲解戳我
tarjan 求强连通分量 基础模板:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=1e5+5;
vector<int> mp[maxn];
int dfn[maxn],low[maxn];
bool ins[maxn];
int tim,cnt;
stack<int> s;
int color[maxn],colornum[maxn];
int n,m;
void tarjan(int u){
++tim;
dfn[u]=low[u]=tim;
s.push(u);
ins[u]=true;
for(int tp:mp[u]){
if(dfn[tp]==0){
tarjan(tp);
low[u]=min(low[u],low[tp]);
}
else if(ins[tp]==true){
low[u]=min(low[u],dfn[tp]);
}
}
if(low[u]==dfn[u]){
cnt++;
while(s.top()!=u){
int tp=s.top();
s.pop();
color[tp]=cnt;
colornum[cnt]++;
ins[tp]=false;
}
s.pop();
color[u]=cnt;
colornum[cnt]++;
ins[u]=false;
}
}
int main(){
std::ios::sync_with_stdio(0);
cin>>n>>m;
int x,y;
for(int i=1;i<=m;++i){
cin>>x>>y;
mp[x].push_back(y);
}
for(int i=1;i<=n;++i){
if(dfn[i]==0){
tarjan(i);
}
}
return 0;
}
tarjan 求割点 基础模板:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e4+5;
vector<int> mp[maxn];
int n,m;
int low[maxn];
int dfn[maxn];
int tim;
set<int> ans;
void tarjan(int u,int fa){
++tim;
low[u]=dfn[u]=tim;
int child=0;
for(int v:mp[u]){
if(dfn[v]==0){
child++;
tarjan(v,fa);
low[u]=min(low[u],low[v]);
if(u!=fa && low[v]>=dfn[u]){
ans.insert(u);
}
}
else{
low[u]=min(low[u],dfn[v]);
}
}
if(child>=2 && u==fa) ans.insert(fa);
}
int main(){
std::ios::sync_with_stdio(0);
cin>>n>>m;
int x,y;
for(int i=1;i<=m;++i){
cin>>x>>y;
mp[x].push_back(y);
mp[y].push_back(x);
}
for(int i=1;i<=n;++i){
if(dfn[i]==0) tarjan(i,i);
}
cout<<ans.size()<<endl;
for(int i:ans){
cout<<i<<' ';
}
return 0;
}