一.有向图强连通
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<cctype>
using namespace std;
const int N = 5000005;
const int M = 5000005;//链式前向星存的是边,m*m
int x,y,n,m,pointnum,cnt,Ind,top,ans;//targan模板题
int head[N<<2],nxt[M],to[M];
int low[N],dfn[N],stack[N];
int belong[N],ru[N];
bool in[N];
int a;
inline void add(int x,int y){
nxt[++cnt]=head[x];
head[x]=cnt;
to[cnt]=y;
}
inline void dfs(int x){
low[x]=dfn[x]=++Ind;
stack[++top]=x;in[x]=true;
for(int i=head[x];i;i=nxt[i]){
int v=to[i];
if(!dfn[v]){
dfs(v);
low[x]=min(low[x],low[v]);
}
else if(in[v]) low[x]=min(low[x],dfn[v]);
}
if(low[x]==dfn[x]){
++pointnum;
int j=-1;
while(j!=x){
j=stack[top--];
belong[j]=pointnum;
in[j]=false;
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a;
if(a)add(i,j);
}
}
// for(int i=1;i<=m;i++){
////
// if(x!=y) add(x,y);
// }
for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
for(int i=1;i<=n;i++)
for(int e=head[i];e;e=nxt[e])
if(belong[i]!=belong[to[e]])
ru[belong[to[e]]]++;
for(int i=1;i<=pointnum;i++)
if(!ru[i]) ans++;
cout<<ans<<endl;
return 0;
}
二.无向图割点与桥、双连通
三.LCA
待更