朋友圈

参看 并查集的tutorial http://blog.csdn.net/jiyanfeng1/article/details/8083789

参考 基于并查集的算法 http://blog.csdn.net/jiyanfeng1/article/details/39257119


假如已知有n个人和m对好友关系,如果两个人是直接或者间接有好友关系,则认为他们属于同一个朋友圈。写程序判断里面有多少朋友圈。

例如:
n = 5, m = 3  r = {(1,2), (2, 3), (4, 5)}  1 2 3 是一个朋友圈, 4 5 是一个朋友圈。

所以输出是2.


下面的算法是基于图论中的深度优先的思想。

#include <STDIO.H>  
#include <WINDOWS.H>  
  
  
int Friends(int n, int m , int* r[]);  
  
int main(int argc,char** argv)  
{   
  int r[5][2] = {{1,2},{4,3},{6,5},{7,8},{7,9}};  
   
  printf("有%d个朋友圈。\n",Friends(0,5,(int**)r));  
  return 0;  
}  
  
int Friends(int n, int m, int* r[]) // 注意这里的参数很奇葩    
{  
   
  int *p = (int*)malloc(sizeof(int)*m*3);  
  
  memset(p,0,sizeof(int)*m*3);  
  int i = 0;  
  
  int iCount = 0;  
  
  int j = 0;  
  
  int * q = (int*)r; // 这里很巧妙  将二维指针 强转为一维指针  
  
  for (i=0;i<m;++i)  
  {  
    for (j=0;j<2;++j)  
    {  
      p[i*3+j]=q[i*2+j];   // 注意这里二维数组向一维数组的转换  
    }  
  
    p[i*3+j] = 0;  
  }  
  
  bool bFlag = false;  
  
  for (i=0;i<m;++i)  
  {  
    bFlag = false;  
    if (p[i*3+2]==1)  
    {  
       bFlag = true;  
    }  
    p[i*3+2] = 1;  
    for (j=0;j<m;++j)  
    {  
      if (i==j)  
      {  
        continue;  
      }   
       
  
      if (p[i*3]==p[j*3] ||  
        p[i*3] == p[j*3+1] ||  
        p[i*3+1] == p[j*3+0] ||  
        p[i*3+1] == p[j*3+1])  
      {  
        if (p[j*3+2]==1)  
        {  
          bFlag = true;  
        }  
        p[j*3+2] = 1;  
      }  
    }  
  
    if (!bFlag)  
    {  
      ++iCount;  
    }  
  }  
  
  free(p);   
    
  return iCount;  
}  

另外一个更加简洁的算法是:基于图论的广度优先算法。

给定保存了朋友关系的数组 r ,然后依次扫描数组 r 中的朋友

如果数组中的一对朋友hash set里面找不到,那么朋友圈个数就加1,并且把这两个人加入到 hash set 里。

如果这一对朋友里的任何一个人,在hash set 里找的到,那么朋友圈个数不变,并把这两个人中另外一个不在hash set里的人加入到hash set 里 (如果两个人都已经在hashet 里,那么就什么都不做。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值