7 、 图论—连通性

7.1 无向图关键点(dfs 邻接阵)

//无向图的关键点,dfs 邻接阵形式,O(n^2)
//返回关键点个数,key[]返回点集
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 110
void search(int n,int mat[][MAXN],int* dfn,int* low,int now,int& ret,int* key,int& cnt,int
root,int& rd,int* bb){
int i;
dfn[now]=low[now]=++cnt;
for (i=0;i<n;i++)
if (mat[now][i]){
if (!dfn[i]){
search(n,mat,dfn,low,i,ret,key,cnt,root,rd,bb);
if (low[i]<low[now])
low[now]=low[i];
if (low[i]>=dfn[now]){
if (now!=root&&!bb[now])
key[ret++]=now,bb[now]=1;
else if(now==root)
rd++;
}
}
else if (dfn[i]<low[now])
low[now]=dfn[i];
}
}
int key_vertex(int n,int mat[][MAXN],int* key){
int ret=0,i,cnt,rd,dfn[MAXN],low[MAXN],bb[MAXN];
for (i=0;i<n;dfn[i++]=bb[i]=0);
for (cnt=i=0;i<n;i++)
if (!dfn[i]){
rd=0;
search(n,mat,dfn,low,i,ret,key,cnt,i,rd,bb);
if (rd>1&&!bb[i])
key[ret++]=i,bb[i]=1;
}
return ret;
}

7.2 无向图关键边(dfs 邻接阵)

//无向图的关键边,dfs 邻接阵形式,O(n^2)
//返回关键边条数,key[][2]返回边集
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
void search(int n,int mat[][MAXN],int* dfn,int* low,int now,int& cnt,int key[][2]){
int i;
for (low[now]=dfn[now],i=0;i<n;i++)
if (mat[now][i]){
if (!dfn[i]){
dfn[i]=dfn[now]+1;
search(n,mat,dfn,low,i,cnt,key);
if (low[i]>dfn[now])
key[cnt][0]=i,key[cnt++][1]=now;
if (low[i]<low[now])
low[now]=low[i];
}
else if (dfn[i]<dfn[now]-1&&dfn[i]<low[now])
low[now]=lev[i];
}
}
int key_edge(int n,int mat[][MAXN],int key[][2]){
int ret=0,i,dfn[MAXN],low[MAXN];
for (i=0;i<n;dfn[i++]=0);
for (i=0;i<n;i++)
if (!dfn[i])
dfn[i]=1,bridge(n,mat,dfn,low,i,ret,key);
return ret;
}

7.3 无向图的块(bfs 邻接阵)

7.3 无向图的块(bfs 邻接阵)
//无向图的块,dfs 邻接阵形式,O(n^2)
//每产生一个块调用 dummy
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
#include <iostream.h>
void dummy(int n,int* a){
for (int i=0;i<n;i++)
cout<<a[i]<<' ';
cout<<endl;
}
void search(int n,int mat[][MAXN],int* dfn,int* low,int now,int& cnt,int* st,int& sp){
int i,m,a[MAXN];
dfn[st[sp++]=now]=low[now]=++cnt;
for (i=0;i<n;i++)
if (mat[now][i]){
if (!dfn[i]){
search(n,mat,dfn,low,i,cnt,st,sp);
if (low[i]<low[now])
low[now]=low[i];
if (low[i]>=dfn[now]){
80
for (st[sp]=-1,a[0]=now,m=1;st[sp]!=i;a[m++]=st[--sp]);
dummy(m,a);
}
}
else if (dfn[i]<low[now])
low[now]=dfn[i];
}
}
void block(int n,int mat[][MAXN]){
int i,cnt,dfn[MAXN],low[MAXN],st[MAXN],sp=0;
for (i=0;i<n;dfn[i++]=0);
for (cnt=i=0;i<n;i++)
if (!dfn[i])
search(n,mat,dfn,low,i,cnt,st,sp);
}

7.4 无向图连通分支(dfs/bfs 邻接阵)

//无向图连通分支,dfs 邻接阵形式,O(n^2)
//返回分支数,id 返回 1..分支数的值
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
void floodfill(int n,int mat[][MAXN],int* id,int now,int tag){
int i;
for (id[now]=tag,i=0;i<n;i++)
if (!id[i]&&mat[now][i])
floodfill(n,mat,id,i,tag);
}
int find_components(int n,int mat[][MAXN],int* id){
int ret,i;
for (i=0;i<n;id[i++]=0);
for (ret=i=0;i<n;i++)
if (!id[i])
floodfill(n,mat,id,i,++ret);
return ret;
}
//无向图连通分支,bfs 邻接阵形式,O(n^2)
//返回分支数,id 返回 1..分支数的值
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
int find_components(int n,int mat[][MAXN],int* id){
int ret,k,i,j,m;
for (k=0;k<n;id[k++]=0);
for (ret=k=0;k<n;k++)
if (!id[k])
for (id[k]=-1,ret++,m=1;m;)
for (m=i=0;i<n;i++)
if (id[i]==-1)
for (m++,id[i]=ret,j=0;j<n;j++)
if (!id[j]&&mat[i][j])
id[j]=-1;
return ret;
}

7.5 有向图强连通分支(dfs/bfs 邻接阵)

//有向图强连通分支,dfs 邻接阵形式,O(n^2)
//返回分支数,id 返回 1..分支数的值
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
void search(int n,int mat[][MAXN],int* dfn,int* low,int now,int& cnt,int& tag,int* id,int* st,int&
sp){
int i,j;
dfn[st[sp++]=now]=low[now]=++cnt;
for (i=0;i<n;i++)
if (mat[now][i]){
if (!dfn[i]){
ssearch(n,mat,dfn,low,i,cnt,tag,id,st,sp);
if (low[i]<low[now])
low[now]=low[i];
}
else if (dfn[i]<dfn[now]){
for (j=0;j<sp&&st[j]!=i;j++);
if (j<cnt&&dfn[i]<low[now])
low[now]=dfn[i];
}
}
if (low[now]==dfn[now])
for (tag++;st[sp]!=now;id[st[--sp]]=tag);
}
int find_components(int n,int mat[][MAXN],int* id){
int ret=0,i,cnt,sp,st[MAXN],dfn[MAXN],low[MAXN];
82
for (i=0;i<n;dfn[i++]=0);
for (sp=cnt=i=0;i<n;i++)
if (!dfn[i])
search(n,mat,dfn,low,i,cnt,ret,id,st,sp);
return ret;
}
//有向图强连通分支,bfs 邻接阵形式,O(n^2)
//返回分支数,id 返回 1..分支数的值
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
#define MAXN 100
int find_components(int n,int mat[][MAXN],int* id){
int ret=0,a[MAXN],b[MAXN],c[MAXN],d[MAXN],i,j,k,t;
for (k=0;k<n;id[k++]=0);
for (k=0;k<n;k++)
if (!id[k]){
for (i=0;i<n;i++)
a[i]=b[i]=c[i]=d[i]=0;
a[k]=b[k]=1;
for (t=1;t;)
for (t=i=0;i<n;i++){
if (a[i]&&!c[i])
for (c[i]=t=1,j=0;j<n;j++)
if (mat[i][j]&&!a[j])
a[j]=1;
if (b[i]&&!d[i])
for (d[i]=t=1,j=0;j<n;j++)
if (mat[j][i]&&!b[j])
b[j]=1;
}
for (ret++,i=0;i<n;i++)
if (a[i]&b[i])
id[i]=ret;
}
return ret;
}

7.6有向图最小点基( 邻接阵)

//有向图最小点基,邻接阵形式,O(n^2)
//返回电集大小和点集
//传入图的大小 n 和邻接阵 mat,不相邻点边权 0
//需要调用强连通分支
#define MAXN 100
83
int base_vertex(int n,int mat[][MAXN],int* sets){
int ret=0,id[MAXN],v[MAXN],i,j;
j=find_components(n,mat,id);
for (i=0;i<j;v[i++]=1);
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (id[i]!=id[j]&&mat[i][j])
v[id[j]-1]=0;
for (i=0;i<n;i++)
if (v[id[i]-1])
v[id[sets[ret++]=i]-1]=0;
return ret;
}
原文地址:https://www.cnblogs.com/godoforange/p/11240564.html