小米笔试的最后一题就是图论的一道题,仔细写了一下答案,结果在gcc和vs下都测试通过:
就是一个找无向图的连通子图问题,通过图上面的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; }