求连通分量
ssl 1759
题目大意
由n个点组成的无向图,求连通在一起的点数最大是多少
原题
求一个图的连通分量

Input
n 顶点数(<=100)
边
Output
连通分量
Sample Input
8
6 3
1 2
2 5
5 4
4 1
8 7
0 0
Sample Output
4
方法一(dfs 邻接矩阵)
用邻接矩阵的方法来存,再用dfs,要判断到过没
#include<cstdio>
#include<iostream>
using namespace std;
int n,x,y,a[101][101],ans;
bool p[101];
int dfs(int now)
{
int t=1;
p[now]=1;
for (int i=1;i<=n;i++)
if ((!p[i])&&(a[now][i]))
t+=dfs(i);
return t;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
while(x&&y)
{
a[x][y]=1;
a[y][x]=1;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
if (!p[i])
ans=max(ans,dfs(i));
printf("%d",ans);
}
方法二(dfs 邻接表)
用dfs,但是用链表的方法存,搜索时就省了很多时间
#include<cstdio>
#include<iostream>
using namespace std;
int s[101],n,x,y,ans,w;
bool p[101];
struct rec
{
int ss,next;
}a[10005];
int dfs(int now)
{
int t=1;
p[now]=1;
for (int i=s[now];i;i=a[i].next)
if (!p[a[i].ss]) t+=dfs(a[i].ss);
return t;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
while (x&&y)
{
a[++w].ss=y;
a[w].next=s[x];
s[x]=w;
a[++w].ss=x;
a[w].next=s[y];
s[y]=w;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
if (!p[i])
ans=max(ans,dfs(i));
printf("%d",ans);
}
方法三(bfs 邻接矩阵)
同样是用邻接矩阵,但用bfs,从每一个位置开始,结果为队列的长度
**#include<cstdio>
#include<iostream>
using namespace std;
int n,x,y,a[101][101],p[101],d[101],ans;
int bfs(int x)
{
int head=0,tail=1;
d[1]=x;
p[x]=1;
do
{
head++;
for (int i=1;i<=n;i++)
if ((!p[i])&&(a[d[head]][i]))
{
d[++tail]=i;
p[i]=1;
}
}while(head<=tail);
return tail;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
while (x&&y)
{
a[x][y]=1;
a[y][x]=1;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
if (!p[i])
ans=max(ans,bfs(i));
printf("%d",ans);
return 0;
}**
方法四(bfs 邻接表)
用bfs和邻接表(二+三),内容基本就是方法二和方法三的合成体
#include<cstdio>
#include<iostream>
int n,x,y,w,ans,p[101],s[101],d[101];
using namespace std;
struct rec
{
int ss,next;
}a[10005];
int bfs(int now)
{
int head=0,tail=1;
d[1]=now;
p[now]=1;
do
{
head++;
for (int i=s[d[head]];i;i=a[i].next)
if (!p[a[i].ss])
{
p[a[i].ss]=1;
d[++tail]=a[i].ss;
}
}while(head<=tail);
return tail;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
while (x&&y)
{
a[++w].ss=y;
a[w].next=s[x];
s[x]=w;
a[++w].ss=x;
a[w].next=s[y];
s[y]=w;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
if (!p[i])
ans=max(ans,bfs(i));
printf("%d",ans);
return 0;
}
方法五The last(bfs 邻接表——
S
T
L
{\color{Red}STL}
STL)
个方法四基本相同,但运用了一种鲜为人我知的技术——STL(queue),改了一些地方
#include<cstdio>
#include<iostream>
#include<queue>
int n,x,y,w,ans,p[101],s[101],d[101];
using namespace std;
struct rec
{
int ss,next;
}a[10005];
int bfs(int now)
{
int g,jg=1;
queue<int>d;
d.push(now);
p[now]=1;
while(d.size())
{
g=d.front();
d.pop();
for (int i=s[g];i;i=a[i].next)
if (!p[a[i].ss])
{
jg++;
p[a[i].ss]=1;
d.push(a[i].ss);
}
}
return jg;
}
int main()
{
scanf("%d%d%d",&n,&x,&y);
while (x&&y)
{
a[++w].ss=y;
a[w].next=s[x];
s[x]=w;
a[++w].ss=x;
a[w].next=s[y];
s[y]=w;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
if (!p[i])
ans=max(ans,bfs(i));
printf("%d",ans);
return 0;
}