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; }