【DFS】【BFS】【邻接表】【STL】求连通分量

-Description -

求一个图的连通分量
【DFS】【BFS】【邻接表】【STL】求连通分量_第1张图片
-Input-

n 顶点数(<=100)

-Output-

连通分量(例子为4)


方法:

(就当是摸鱼吧)

  1. DFS+邻接矩阵
  2. DFS+邻接表
  3. BFS+邻接矩阵+STL(链表)
  4. BFS+邻接表+STL

1.DFS+邻接矩阵

很快就打完了(最简单了)

#include
using namespace std;
int ans=0,n,l;
bool f[101][101],B[101];
void dfs(int k){           //搜
	++l;
	for(int i=1;i<=n;++i)  //循环每个节点
	  if(f[k][i]&&k!=i&&B[i]==false){  //如果他们连通且没走过
	  	B[i]=true;  //赋值为走过
	  	dfs(i);     //继续搜
	  }
}
int main(){
	int x,y;
    scanf("%d%d%d",&n,&x,&y);
    while(x&&y){
        f[x][y]=1;  //x可以通往y
        f[y][x]=1;  //y可以通往x
        scanf("%d%d",&x,&y);  //输入
    }
    for(int i=1;i<=n;++i)    //循环找没走过的点
      if(B[i]==false)
      {     //因为此点走过,说明它和别的点组成的连通图被搜过
      	B[i]=true; l=0; //初始
      	dfs(i);  //搜
      	if(ans<l) ans=l;
      }	
    printf("%d",ans);
}

2.DFS+邻接表

耗了一点时间弄明白邻接表

#include
using namespace std;
int ans=0,n,l,t=0,ls[101]; //ls[x] 以x出发,到达的最后一个点在a中的位置
bool B[101];
struct C{
	int y,next;  //y为链接的点,next为上一个 链接x的点 存的位置
} a[203];
void bfs(int k){
	l++; //连通的点的数量+1
	for(int i=ls[k];i;i=a[i].next)  //i等于链接k的路径的位置
	  if(B[a[i].y]==false){  //路径连通的点没走过
	  	B[a[i].y]=true;  //置为走过
	  	bfs(a[i].y);   //搜
	  }
}
int main(){
	int x,y;
    scanf("%d%d%d",&n,&x,&y);
    while(x&&y){
    	a[++t].y=y;a[t].next=ls[x]; ls[x]=t;
    	//此路径可以到y;上一个链接x点的路径的位置;链接x点的最后一条路径的位置为t
    	a[++t].y=x;a[t].next=ls[y]; ls[y]=t;
    	//因为是无向图。。。同上
        scanf("%d%d",&x,&y);
    }
    for(int i=1;i<=n;++i)
      if(B[i]==false){ //没搜过
      	B[i]=true;
      	l=0;  //初始化
      	bfs(i);  //搜i连通的所有点
      	if(l>ans) ans=l; //取最大值
      }
    printf("%d",ans);
}

3.BFS+邻接矩阵+STL

emmmm就是调试用了点时间。
用了链表什么队列的头和尾都不用管了,数组也省了

#include
#include   //STL的头文件
using namespace std;
int n,L,ans=0;
bool f[101][101],B[101];
void bfs(int k){
	queue<int> Q;      //定义链表Q
	Q.push(k);         //将当前点加入Q
	while(Q.size()){   //当Q长度不为0,就是还有点可以搜
		int l=Q.front();  //l=Q队列头的那个点
		Q.pop();  //弹出那个点
		for(int i=1;i<=n;++i)   //往这个点通往的地方搜索
		  if(B[i]==false&&f[l][i]&&l!=i){ //没走过且连通
		  	B[i]=true; //走过
		  	++L;  //连接的点+1
		  	Q.push(i);  //将此点加入链表
		  }
	}
}
int main(){
	int x,y;
	scanf("%d%d%d",&n,&x,&y);
	while(x&&y){       //输入,跟前面一模一样。。。
		f[x][y]=1;
		f[y][x]=1;
		scanf("%d%d",&x,&y);
	}
	for(int i=1;i<=n;++i)
	if(B[i]==false){   //搜,也是一模一样
		B[i]=true;   //走过
		L=1;    //自身置1
		bfs(i);   //搜
		if(L>ans)ans=L;  //求最大值
	}
	printf("%d",ans);
}

4.BFS+邻接表+STL

复制粘贴使我快乐(雾)

#include
#include   //STL的头文件
using namespace std;
int n,L,ans=0,ls[101],t=0;
bool B[101];
struct C{
	int y,next;  //y为链接的点,next为上一个 链接x的点 存的位置
} a[203];
void bfs(int k){
	queue<int> Q;      //定义链表Q
	Q.push(k);         //将当前点加入Q
	while(Q.size()){   //当Q长度不为0,就是还有点可以搜
		int l=Q.front();  //l=Q队列头的那个点
		Q.pop();  //弹出那个点
		for(int i=ls[l];i;i=a[i].next)   //i等于链接k的路径的位置
		  if(B[a[i].y]==false){ //没走过
		  	B[a[i].y]=true; //走过
		  	++L;  //连接的点+1
		  	Q.push(a[i].y);  //将此点加入链表
		  }
	}
}
int main(){
	int x,y;
	scanf("%d%d%d",&n,&x,&y);
	while(x&&y){
    	a[++t].y=y;a[t].next=ls[x]; ls[x]=t;
    	//此路径可以到y;上一个链接x点的路径的位置;链接x点的最后一条路径的位置为t
    	a[++t].y=x;a[t].next=ls[y]; ls[y]=t;
        scanf("%d%d",&x,&y);
    }
	for(int i=1;i<=n;++i)
	if(B[i]==false){    //没走过
		B[i]=true;   
		L=1;            //初始化
		bfs(i);        //搜
		if(L>ans)ans=L;  
	}
	printf("%d",ans);
}

你可能感兴趣的:(BFS,DFS,图论)