求连通分量
题目链接:求连通分量
题目描述
求一个图的连通分量
输入格式
输入一个数n(n<=100)表示顶点数,下面每行输入两个整数,表示一条边的两个顶点,输入两个0表示结束。
输出格式
一个整数,为这个图的连通分量。
输入输出样例
输入
8
6 3
1 2
2 5
5 4
4 1
8 7
0 0
输出
3
解题思路
这道题方法有很多种,在老师的要求下作者写了5种方法,如果有不太清楚的地方望各位海涵
①深度优先搜索+邻接矩阵
#include<iostream>
using namespace std;
int n,a[110][110],b[110],t,maxn;
void dfs(int now,int star)//深度优先搜索
{
if(b[now])
return;
b[now]=star;
for(int i=1;i<=n;i++)
if(a[now][i])
dfs(i,star);
}
int main()
{
cin>>n;
int x,y;
cin>>x>>y;
if(!(x&&y))//特殊判断
{
cout<<1<<endl;
return 0;
}
while(x||y)//输入
{
a[x][y]=1;
a[y][x]=1;
cin>>x>>y;
}
for(int i=1;i<=n;i++)
{
dfs(i,i);
int s=0;
for(int j=1;j<=n;j++)
if(b[j]==i)
s++;
if(s>maxn)
maxn=s;
}
cout<<maxn<<endl;
}
②深度优先搜索+邻接表
#include<iostream>
using namespace std;
int n,b[110],maxn,ans,hd[110],tot;
struct abc{
int next,to,now;
}a[1100110];
void add(int x,int y)//插入邻接表
{
tot++;
a[tot].now=x;
a[tot].to=y;
a[tot].next=hd[x];
hd[x]=tot;//标记与这个点相连的上一条边
}
void dfs(int now)//深度优先搜索
{
b[now]=1;//标记
for(int j=hd[now];j;j=a[j].next)
if(!b[a[j].to])
{
ans++;
dfs(a[j].to);
}
}
int main()
{
cin>>n;
int x,y;
cin>>x>>y;
while(x&&y)//输入
{
add(x,y);
add(y,x);
cin>>x>>y;
}
for(int i=1;i<=n;i++)
{
if(!b[i])
{
ans=0;
dfs(i);
if(ans>maxn)
maxn=ans;
}
}
cout<<maxn+1<<endl;//还要加上自身的点
}
③广度优先搜索+邻接矩阵
#include<iostream>
using namespace std;
int n,a[110][110],b[110],t,maxn,hd=0,tl=1;
struct abc{
int now,star;
}f[110];
int main()
{
cin>>n;
int x,y;
cin>>x>>y;
if(!(x&&y))
{
cout<<1<<endl;
return 0;
}
while(x||y)
{
a[x][y]=1;
a[y][x]=1;
cin>>x>>y;
}
for(int i=1;i<=n;i++)
{
if(!b[i])
{
tl=1;
hd=0;
f[1].now=i;
while(hd<tl)
{
hd++;
for(int j=1;j<=n;j++)
{
if(a[f[hd].now][j]&&!b[j])
{
b[j]=1;
tl++;
f[tl].now=j;
}
}
}
if(tl>maxn)
maxn=tl;
}
}
cout<<maxn-1<<endl;
}
④广度优先搜索+邻接表
#include<iostream>
using namespace std;
int b[110],n,f[100010],tot,maxn,hd[100010];
struct abc{
int next,to,now;
}a[1100110];
void add(int x,int y)
{
tot++;
a[tot].now=x;
a[tot].to=y;
a[tot].next=hd[x];
hd[x]=tot;
}
int main()
{
int x,y;
cin>>n>>x>>y;
while(x&&y)
{
add(x,y);
add(y,x);
cin>>x>>y;
}
for(int i=1;i<=n;i++)
{
if(!b[i])
{
int tl=1;
int head=0;
f[1]=i;
while(head<tl)
{
head++;
for(int j=hd[f[head]];j;j=a[j].next)
{
if(!b[a[j].to])
{
b[a[j].to]=1;
tl++;
f[tl]=a[j].to;
}
}
}
if(tl>maxn)
maxn=tl;
}
}
cout<<maxn-1<<endl;
}
⑤广度优先搜索+邻接表+queue(队列)
#include<iostream>
#include<queue>
using namespace std;
int b[110],n,tot,maxn,hd[100010];
struct abc{
int next,to,now;
}a[1100110];
void add(int x,int y)
{
tot++;
a[tot].now=x;
a[tot].to=y;
a[tot].next=hd[x];
hd[x]=tot;
}
int main()
{
int x,y;
cin>>n>>x>>y;
while(x&&y)
{
add(x,y);
add(y,x);
cin>>x>>y;
}
for(int i=1;i<=n;i++)
{
if(!b[i])
{
int ans=0;
queue<int>f;
f.push(i);
while(f.size())
{
for(int j=hd[f.front()];j;j=a[j].next)
{
if(!b[a[j].to])
{
b[a[j].to]=1;
f.push(a[j].to);
ans++;
}
}
f.pop();
}
if(ans>maxn)
maxn=ans;
}
}
cout<<maxn<<endl;
}
后面的三个作者都没有加标,因为大部分和上面差不多,最后一个作者也不太懂 。