求连通块
Time Limit: 1sec Memory Limit:256MB
Description
输入一个简单无向图,求出图中连通块的数目。
Input
输入的第一行包含两个整数n和m,n是图的顶点数,m是边数。1<=n<=100,0<=m<=10000。
以下m行,每行是一个数对u v,表示存在边(u,v)。顶点编号从1开始。
Output
单独一行输出连通块的数目。
Sample Input
5 3
1 2
1 3
2 4
Sample Output
2
这个题目很简单,我们时需要对整个图运用深度优先搜索。因为深度优先搜索算法需要保证每个顶点都被访问,所以他是依次访问各个独立的块的。因此,我们可以简化搜索算法,同时在里面加入一行统计次数的代码即可。
《算法导论》22章,图的基本算法,深度优先搜索。
DFS(G)
For each vetex u in V[G]
Do color[u] = white
For each vetex u in V[G]
Do if clolor[u] is white
Then DFS-VISIT(u)
DFS-VISIT(u)
Color[u] = gray
For each v in u’s neighbor
If color[v] == white
Then DFS-VISIT(v)
Color[u] = black
#include <stdio.h>
#include <malloc.h>
#include <queue>
using std::queue;
const int MAX = 100;
typedef enum color {
white = 0,
gray = 1,
black = 2
} color;
typedef struct node {
int data;
node * next;
color c;
} node;
bool DFS_Visit(node *G[MAX], int s, int n);
int DFS_blocks(node *G[MAX], int n);
node * tail(node * head);
void print_G(node *G[MAX], int n);
// for test
void print_G(node *G[MAX], int n) {
int i;
node * travel;
for(i = 0; i < n; i++) {
travel = G[i];
printf("%d (color : %d)->", travel->data, travel->c);
travel = travel->next;
while(travel != NULL) {
printf("%d->", travel->data);
travel = travel->next;
}
printf("NULL\n");
}
printf("\n");
}
int DFS_blocks(node *G[MAX], int n) {
int i;
int res = 0;
for(i = 0; i < n; i++) {
G[i]->c = white;
}
for(i = 0; i <n; i++) {
if(DFS_Visit(G, i, n))
res++;
}
return res;
}
bool DFS_Visit(node *G[MAX], int s, int n) {
if(G[s]->c == black)
return false;
G[s]->c = gray;
queue<node *> q;
node * u;
node * travel;
q.push(G[s]);
while(!q.empty()) {
u = q.front();
q.pop();
travel = u->next;
while(travel != NULL) {
if(G[travel->data-1]->c == white) {
G[travel->data-1]->c = gray;
q.push(G[travel->data-1]);
}
travel = travel->next;
}
// print_G(G ,n);
u->c = black;
}
return true;
}
node * tail(node * head) {
node * travel = head;
while(travel -> next != NULL)
travel = travel->next;
return travel;
}
int main() {
int n; // vetrix shu
int m; // bian shu
int v; // ding dian a
int u; // ding dian b
int i;
node *G[MAX];
node * temp1 = NULL;
node * temp2 = NULL;
scanf("%d %d", & n, &m);
for(i = 0; i < n; i++) {
G[i] = (node *)malloc(sizeof(node));
G[i]->data = i+1;
G[i]->next = NULL;
}
for(i = 0; i < m; i++) {
scanf("%d %d", &u, &v);
temp1 = (node *)malloc(sizeof(node));
temp1->data = v;
temp1->next = NULL;
temp2 = (node *)malloc(sizeof(node));
temp2->data = u;
temp2->next = NULL;
tail(G[u-1])->next = temp1;
tail(G[v-1])->next = temp2;
}
printf("%d\n", DFS_blocks(G, n));
return 0;
}
参考:
《算法导论》22章