标题求图中的分量的个数连通
今天翻看LRJ的书籍<<算法竞赛入门经典>>的时候,看见一题十分精彩,其中包含了求图的联通分量的个数。利用了并查集,因为害怕搞忘记了并查集的具体写法,所以记录一下。
原题:
Your task is to divide a number of persons into two teams, in such a way, that:
- everyone belongs to one of the teams;
- every team has at least one member;
- every person in the team knows every other person in his team;
- teams are as close in their sizes as possible.
Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.Output
For simplicity, all persons are assigned a unique integer identifier from 1 to N.The first line in the input file contains a single integer number N (2 ≤ N ≤ 100) - the total number of persons to divide into teams, followed by N lines - one line per person in ascending order of their identifiers. Each line contains the list of distinct numbers Aij (1 ≤ Aij ≤ N, Aij ≠ i) separated by spaces. The list represents identifiers of persons that ith person knows. The list is terminated by 0.
#include<bits/stdc++.h>
#define _for(a,b,i) for(int i=a;i<=b;i++)
using namespace std;
const int INF = 1e3;
int graph[INF][INF];
int f[INF];
int find(int x){
return f[x]==x?f[x]:f[x]=find(f[x]);
}
int add(int x,int y){
f[find(x)] = find(y);
return 1;
}
int main(){
int n,edge;
while(cin>>n&&n){
_for(1,n,i){
f[i] = i;
}
memset(graph,0,sizeof(graph));
cin>>edge;
for(int i=0;i<edge;i++){
int number,number1;
graph[number][number1] = 1;
add(number,number1);
}
int sum = 0;
_for(1,n,i){
if(f[i]==i) sum++;
}
cout<<"连通分量的个数:"<<sum<<endl;
}
return 0;
}