求某点的所在连通块的总点数,至少有三种解法: dfs, bfs, 并查集
dfs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
using namespace std;
int n,m;
const int maxn=30001;
vector<int> adj[maxn];
int list[30001];
bool vis[maxn];
void dfs(int i) {
if(vis[i])
return;
vis[i]=1;
for(int j=0;j<adj[i].size();j++)
{
int p=adj[i][j];
dfs(p);
}
}
int main() {
while(scanf("%d%d",&n,&m) !=EOF) {
if(!(n|m))
break;
int i,j,k;
for(i=0;i<n;i++)
adj[i].clear();
int t;
for(i=0;i<m;i++)
{
scanf("%d",&t);
for(j=0;j<t;j++)
{
scanf("%d",&list[j]);
}
for(j=0;j<t-1;j++)
{
adj[list[j]].push_back(list[j+1]);
adj[list[j+1]].push_back(list[j]);
}
}
memset(vis,0,sizeof(vis));
dfs(0);
int cnt=0;
for(i=0;i<n;i++)
{
if(vis[i])
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
bfs:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <queue>
using namespace std;
int n,m;
const int MAXN=30001;
bool vis[MAXN];
vector<int> adj[MAXN];
int list[MAXN];
int main() {
while(scanf("%d%d",&n,&m)!=EOF) {
if(!(n|m))
break;
int i,j,k;
for(i=0;i<n;i++)
adj[i].clear();
int t;
for(k=0;k<m;k++)
{
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&list[i]);
}
for(i=0;i<t-1;i++)
{
adj[list[i]].push_back(list[i+1]);
adj[list[i+1]].push_back(list[i]);
}
}
int cnt=0;
queue<int>q;
memset(vis,0,sizeof(vis));
q.push(0);
while(!q.empty()) {
int p=q.front();
q.pop();
vis[p]=1;
for(i=0;i<adj[p].size();i++)
{
int tmp=adj[p][i];
if(!vis[tmp]) {
q.push(tmp);
}
}
}
for(i=0;i<n;i++)
{
if(vis[i])
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
并查集:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n,m;
const int MAXN=30001;
int rank[MAXN],p[MAXN],num[MAXN];
void init() {
for(int i=0;i<n;i++)
{
p[i]=i;
rank[i]=0;
num[i]=1;
}
}
int find(int x) {
if(x!=p[x])
return find(p[x]);
return x;
}
void union_set(int x,int y) {
x=find(x); y=find(y);
if(x==y)
return;
if(rank[x]>rank[y]) {
p[y]=x;
num[x]+=num[y];
}
else {
p[x]=y;
num[y]+=num[x];
if(rank[x]==rank[y])
rank[y]++;
}
}
int main() {
while(~scanf("%d%d",&n,&m)) {
if(!(n|m))
break;
if(m==0) {
printf("1\n");
continue;
}
int i,j,k,t;
int x,y;
init();
for(i=0;i<m;i++)
{
scanf("%d",&t);
scanf("%d",&x);
for(j=1;j<t;j++)
{
int tmp;
scanf("%d",&tmp);
union_set(x,tmp);
}
}
printf("%d\n",num[find(0)]);
}
return 0;
}