1. 程式人生 > >一共有n個人,給定m對好友關係,好友的好友也算一個朋友圈,問n個人中一共有幾個朋友

一共有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個朋友圈。
package pac;

public class Demo1 {

	/**
	 * @param args
	 * 並查集的應用
	 */
	private int [] set=new int[1000]; //存放上級,如set[5]=3表示5的上級是3

	public int find(int x){ //檢視掌門人
		int r;
		r=x;
		while(set[r]!=r){ //如果掌門人不是自己,一直向上查詢
			r=set[r];
		}
		return r;
	}
	
	public void join(int x,int y){ //讓兩個人做朋友
		int fx=find(x); //找到到x的掌門
		int fy=find(y); //找到y的掌門
		if(fx!=fy) { //如果不是同一個人
			set[fx]=fy;
		}
	}
	
	public int friends(int n,int m,int [][] r){
		int count=0,i;
		for(i=1;i<=n;i++) //初始化並查集
			set[i]=i;
		for(i=0;i<m;i++)
			join(r[i][0],r[i][1]);
		for(i=1;i<=n;i++)
			if(set[i]==i) count++;
		return count;	
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		  System.out.println(new Demo1().friends(5, 3, 
				  new int[][] { { 1, 2 }, { 2, 3 }, { 4, 5 } }));
	}
}
對find()進行路徑優化,由上圖左邊的結構變成右邊的結構
public int find1(int x){ //檢視掌門人,並進行路徑優化
		int r;
		r=x;
		while(set[r]!=r){ //如果掌門人不是自己,一直向上查詢
			r=set[r];
		}
		int i=x,j;
		while(i!=r){
			j=set[i];
			set[i]=r;
			i=j;
		}
		return r;
	}

具體檢視http://www.jianshu.com/p/72ea54bb26ab