边双连通分量
定义
边双连通分量是定义在无向图当中的。
边双连通分量的定义是一个不存在割边的子图。
也就是说图中任意两点都可以有两条不重复(边)的路径可以互相到达。
模板
以P2860 [USACO06JAN]Redundant Paths G为例,给出边双的模板:(其实跟有向图的强连通分量求的代码近乎一模一样)
#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
x=0;bool f=false;char ch=getchar();
while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template <typename T>
inline void write(T x){
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
#define ll long long
#define ull unsigned long long
#define pb push_back
#define rep(i,x,y) for(int i=(x);i<=(y);i++)
#define dep(i,y,x) for(int i=(y);i>=(x);i--)
const int N=1e4+5,M=2e5+5,MOD=1e9+7,V=500;
int n,m,k,cnt,Ans;
int head[N],to[N<<1],nex[N<<1],fr[N<<1],bl[N],idx,ind[N];
bool vis[N<<1];
inline void add(int u,int v){nex[++idx]=head[u];fr[idx]=u;to[idx]=v;head[u]=idx;return;}
int dfn[N],low[N],DFN,sta[N],tp;
void tarjan(int x,int f){//和求SCC几乎一样
dfn[x]=low[x]=++DFN;sta[++tp]=x;
for(register int i=head[x];i;i=nex[i]){
int y=to[i];
if(y==f) continue;
if(!dfn[y]) tarjan(y,x),low[x]=min(low[x],low[y]);
else low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
++cnt;int now;
do{
now=sta[tp--];bl[now]=cnt;
}while(now!=x);
}
return ;
}
#define mp make_pair
#define PII pair<int,int>
map<PII,int>Map;
signed main(){
read(n),read(m);
for(register int i=1,u,v;i<=m;i++) read(u),read(v),add(u,v),add(v,u);
for(register int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
for(register int i=1;i<=idx;i++){
int u=bl[fr[i]],v=bl[to[i]];
if(u!=v&&!Map[mp(u,v)]) ind[v]++,Map[mp(u,v)]=1;
}
for(register int i=1;i<=cnt;i++) if(ind[i]==1) Ans++;
write((Ans+1)>>1);
return 0;
}
/*
*/
性质
其定义就可以作为性质:不存在割边,并且缩点后的图一定是棵树,且树上每一条边都是原图的割边。
其余性质暂时鸽了,有时间想到了再写。

浙公网安备 33010602011771号