小米笔试最后一题

小米笔试的最后一题就是图论的一道题,仔细写了一下答案,结果在gcc和vs下都测试通过:

小米笔试最后一题_第1张图片

就是一个找无向图的连通子图问题,通过图上面的dfs和bfs都可以,下面使用二维数组表示图之间的关系。

这个是vs下面的代码:

// xiaomi.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


#include <stdlib.h>
#include <string.h>

static char* relations;
static char* flag;
static int num;

#define relation(a, b) *(relations + (num) * (a) + (b))
#define set_relation(a, b) relation(a, b)=1

static int alloc_mem(int n){ //分配数组的内存和标志位的内存

	num = n;
	flag = (char*)malloc(num);
	if(!flag)
		return -1;
	memset(flag, 0, num);
	relations = (char*)malloc(num * num);
	if(!relations){
		free(flag);
		return -1;
	}
	memset(relations, 0, num * num);
	return 0;
}

static void free_mem(){
	free(flag);
	free(relations);
}

static void add_relation(int a, int b){ //为无向图添加关联关系
	set_relation(a, b);
	set_relation(b, a);
}

static void dfs_graph(int root){ //dfs搜索

	*(flag + root) = 1;
	int iter = 0;
	while(iter < num){
		if(relation(root, iter) && *(flag + iter) == 0)
			dfs_graph(iter);
		iter ++;
	}

}

static int flag_one(){ //是否所有的节点都遍历到了,如果还有节点没有被访问就返回下一个没有被访问的节点,否则返回-1
	int i;
	for(i = 0; i < num; i++)
		if(*(flag+i) == 0)
			return i;
	return -1;
}

int friends(int n, int m, int r[][2]){ //计算连通子图的个数

	int iter = 0, next = 0;
	int friends_count = 0;
	if(alloc_mem(n) == -1)
		return -1;
	while(iter < m){
		int a = r[iter][0];
		int b = r[iter][1];
		add_relation(a - 1, b-1);
		iter ++;
	}
	while((next = flag_one()) != -1){
		dfs_graph(next);
		friends_count++;
	}
	return friends_count;
}



int _tmain(int argc, _TCHAR* argv[])
{
	int n = 5, m = 3;
	int r[][2] = {{1, 2}, {2, 3}, {4, 5}};
	printf("%d", friends(n, m, r));
	free_mem();
	return 0;
}


你可能感兴趣的:(小米笔试最后一题)