前言:其实关于点双/边双。我觉得hihocoder那2个例子很生动吧。
对于边双就是即使该分量里断了一个边也并不影响连通性,即该分量里没有桥。一个点只能在一个边双分量之中。
对于点双就是该分量里即使断了一个点那还是联通的,即该分量里没有割点,一个点在点双可以在多个点双分量之中。
边双连通分量:hihocoder1184
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
int tot,head[maxn];
struct E{
int to,next;
}edge[maxn<<1];
void add(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m;
int dfn[maxn],low[maxn],vis[maxn<<1],id[maxn],cnt,tott;
int ans[maxn];
stack<int> s;
void tarjan(int x){
low[x]=dfn[x]=++tott;
s.push(x);
for(int i=head[x];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(!vis[i]){
vis[i]=vis[i^1]=1;
if(!dfn[v]){
tarjan(v);
low[x]=min(low[x],low[v]);
}
else{
low[x]</