题目描述
该题的目的是要你统计图的连通分支数。
输入
每个输入文件包含若干行,每行两个整数i,j,表示节点i和j之间存在一条边。
输出
输出每个图的联通分支数。
样例输入 Copy
1 4
4 3
5 5
样例输出 Copy
2
数据量可能很大,一开始用邻接矩阵(二维矩阵,每个维度都是1000)存储,但是一直运行错误,加大了一点矩阵规模后来发现内存超限。后来就改成了邻接表存储。用于标记的数组尽量声明为bool型,节省空间。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int>g[1000000];
int sum;
bool visit[1000000]= {false};
bool book[1000000]={false};
void dfs(int u,int depth)
{
visit[u]=true;
for(int i=0; i<g[u].size(); i++)
{int v=g[u][i];
if(visit[v]==false)
dfs(v,depth+1);
}
}
void dfsg()
{
int u;
for(u=1; u<=n; u++)
{
if(visit[u]==false&&book[u]==true)
{
sum++;
dfs(u,1);
}
}
}
int main()
{
int maxnumber=0,i,j;
while(scanf("%d %d",&i,&j)!=EOF)
{
g[i].push_back(j);
g[j].push_back(i);
book[i]=true;
book[j]=true;
if(i>maxnumber)maxnumber=i;
if(j>maxnumber)maxnumber=j;
}
sum=0;
n=maxnumber;
dfsg();
printf("%d\n",sum);
return 0;
}
也可以用并查集判断:
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int father[1000000];
bool book[1000000];
int findFather(int x)
{
while(x!=father[x])
x=father[x];
return x;
}
void Union(int x,int y)
{
int fatherX=findFather(x);
int fatherY=findFather(y);
if(fatherX!=fatherY)
{
father[fatherX]=fatherY;
}
}
int main()
{
int maxnumber=0,i,j,sum;
for(i=1; i<=1000000; i++)
{
father[i]=i;
}
memset(book,0,sizeof(book));
while(scanf("%d %d",&i,&j)!=EOF)
{
book[i]=1;
book[j]=1;
if(i>maxnumber)maxnumber=i;
if(j>maxnumber)maxnumber=j;
Union(i,j);
}
sum=0;
for(i=1; i<=maxnumber; i++)
{
if(father[i]==i&&book[i]==1)sum++;
}
printf("%d\n",sum);
return 0;
}