一共有n个人,给定m对好友关系,好友的好友也算一个朋友圈,问n个人中一共有几个朋友

题目: 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。假如:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package pac;  
  2.   
  3. public class Demo1 {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      * 并查集的应用 
  8.      */  
  9.     private int [] set=new int[1000]; //存放上级,如set[5]=3表示5的上级是3  
  10.   
  11.     public int find(int x){ //查看掌门人  
  12.         int r;  
  13.         r=x;  
  14.         while(set[r]!=r){ //如果掌门人不是自己,一直向上查找  
  15.             r=set[r];  
  16.         }  
  17.         return r;  
  18.     }  
  19.       
  20.     public void join(int x,int y){ //让两个人做朋友  
  21.         int fx=find(x); //找到到x的掌门  
  22.         int fy=find(y); //找到y的掌门  
  23.         if(fx!=fy) { //如果不是同一个人  
  24.             set[fx]=fy;  
  25.         }  
  26.     }  
  27.       
  28.     public int friends(int n,int m,int [][] r){  
  29.         int count=0,i;  
  30.         for(i=1;i<=n;i++) //初始化并查集  
  31.             set[i]=i;  
  32.         for(i=0;i<m;i++)  
  33.             join(r[i][0],r[i][1]);  
  34.         for(i=1;i<=n;i++)  
  35.             if(set[i]==i) count++;  
  36.         return count;     
  37.     }  
  38.     public static void main(String[] args) {  
  39.         // TODO Auto-generated method stub  
  40.           System.out.println(new Demo1().friends(53,   
  41.                   new int[][] { { 12 }, { 23 }, { 45 } }));  
  42.     }  
  43. }  
对find()进行路径优化,由上图左边的结构变成右边的结构

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public int find1(int x){ //查看掌门人,并进行路径优化  
  2.         int r;  
  3.         r=x;  
  4.         while(set[r]!=r){ //如果掌门人不是自己,一直向上查找  
  5.             r=set[r];  
  6.         }  
  7.         int i=x,j;  
  8.         while(i!=r){  
  9.             j=set[i];  
  10.             set[i]=r;  
  11.             i=j;  
  12.         }  
  13.         return r;  
  14.     }  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值