有向图: 割点:删掉不连通 割边(桥):删掉不连通 连通分量:极大子图 点双连通图:删任意一点仍连通,即 没有割点 边双连通图:删任意一边仍连通,即 没有桥 点双连通分量:极大点双连通子图 边双连通分量:极大边双连通子图 (单点也是边双连通分量)

边双连通:删桥后,双方都是边双

有向图: 弱连通:单向到达 强连通:双向到达(单点也是强连通) 强连通一般用来缩点

求割点和桥的代码(洛谷已过):

int cnt;
int dfn[N];  //表示第几个搜到i点 
int low[N];  //表示i点及其子树通过返祖边连到的最小dfn值 //向下若干次,再通过返祖边向上跳一次 能 跳到的最高点 
void dfs(int x){
	dfn[x]=low[x]=++cnt; 
	int son=0;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].a;
		if(!dfn[y]){  //若y没有被访问过,则其为一个新点 
                        son++;  //son放外面
			dfs(y);
			low(x)=min(low[x],low(y));
			if(low[y]>=dfn(x)){  //y能到达的最高祖点 比 x矮(或就是x) //求桥的话,把等于号去掉即可 
				//son++; //son放外面更好,因为son是用来判断根是否是割点的,而根的儿子y一定不能追溯至根以上,所以不需要放if里,且放外面刚好理解
				if(x!=root || son>=2) vis[x]=1;    //vis为记录割点  //x不是根时,y没有返祖至x以上,则x为割点;fg>=2表示根至少要两个子树才能是割点 
			}
		}
		else low[x]=min(low[x],dfn[y]);  //若y已被访问过,则y就是祖点,此边为返祖边 
	}	
}

以下是kuangbin的模板(一定正确)(原来雨巨是用kuangbin的板子呀,以后我也用) 割点(割点用以下的板子,别用上面的了):

int cnt;
int dfn[N],low[N],vis[N];
void dfs(int x,int fa){
	dfn[x]=low[x]=++cnt;
	int son=0;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].a;
		if(y==fa) continue;
		if(!dfn[y]){
			son++;
			dfs(y,x);
			low[x]=min(low[x],low[y]);
            /*两种判断割点条件的写法,以后用第二种
			第一种【第一种和雨巨的神似】:*/ 
			/*if(dfn[x]<=low[y]){
				if(x!=fa || son>1) vis[x]=1;
			} */
			if(x!=fa&&dfn[x]<=low[y]) vis[x]=1; //第二种写法,用此写法,下面记得特判根 //x!=fa表示非根 	
		}
		else if(y!=fa) low[x]=min(low[x],dfn[y]);  //这里的if条件可以省略,因为y==fa时 continue了 
	}
	if(x==fa&&son>=2) vis[x]=1; 
}

求强连通分量的代码: 强连通分量:任意两点可以互达,若边权为0,则可将整个强连通分量缩点

int cnt;
int dfn[N],low[N];
stack<int>s;
void dfs(int x){
	dfn[x]=low[x]=++cnt;
	s.push(x);
	vis[x]=1;   //记录x是否在栈中,且记录是否被访问过
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].a;
		if(!dfn[y]){  //判断y是否被访问过
			dfs(y);
			low[x]=min(low[x],low[y]);
		}
		else if(vis[y]) low[x]=min(low[x],dfn[y]);  //else表示y被访问过,vis[y]=1表示y被访问过【即y为祖点】且还在栈中【即没有作为强连通分量的一部分弹出。y就是强连通分量的一部分,单点也是强分】,那么此处就有(一个)环【即强连通分量】
//以上if和else 都不满足,则表示被访问过且不在栈中,即 被作为强连通分量的一部分弹出了
	}
	if(dfn[x]==low[x]){ //dfn==low说明下面没有返祖到x以上的点,则要么返到x以下的点成环,要么返祖返到x成环,所以x为强连通分量的最高点  //单点也属于强连通分量
		ans++;  //强连通分量的数量++
		do{
			int t=s.top();s.pop();
			v[t]=0;
			num[t]=ans;  //num[i]表示i为哪一个强连通分量
		} while(x!=t);
	}	
}