合根植物 (一道并查集模板题)

蓝桥杯B组试题
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?

public class Main {
    
    
	
	static int[] pre = new int [1000001];
	static int ans = 0;
	
	private static int find(int root) {
    
    		
		// 暂时存储当前元素
		int t = root;
		while (root != pre[root]) {
    
     // 当当前元素的父元素不是自己本身就不断往上找 
			root = pre[root];// root存储当前元素的父元素
		}
		
		while (t != pre[t]) {
    
    //优化,降低当前树的深度
			int z = t;
			t = pre[t];
			pre[z] = root;//改写find及所有父元素为根
		}
		return root;

//	递归做法
//		if (root != pre[root]) {
    
    
//			root = find(pre[root]);
//		}
//		return root;
	}
	
	private static void uni(int x, int y) {
    
    
		pre[find(x)] = find(y);
	}
	
	public static void main(String[] args) {
    
    
		int m, n, k;
		Scanner sc = new Scanner(System.in);
		m = sc.nextInt();
		n = sc.nextInt();
		k = sc.nextInt();
		for (int i = 0; i <= m * n; i++)
			pre[i] = i;
		for (int i = 0; i < k; i++) {
    
    
			int t1, t2;
			t1 = sc.nextInt();
			t2 = sc.nextInt();
			uni(t1, t2);
		}	
	    for (int i = 1; i <= m * n; i++)     //在题目范围内统计根元素(当前值的标记数组中存储的是自己本身)
	    	if (find(i) == i) ans++;
	    sc.close();
	    System.out.println(ans);  
	}
}

猜你喜欢

转载自blog.csdn.net/qq_45689267/article/details/109118749