2005年浙江大学计算机及软件工程研究生机试真题并查集UnionFindjava实现

18 篇文章 0 订阅
7 篇文章 0 订阅

//并查集中将两个阵营的团队结合
	public static void mix(int pre[],int x,int y)
	{
		int a = findRoot(pre,x);
		int b = findRoot(pre,y);
		if(a!=b)
			pre[a] = b;//赋有将共同的boss
	}

并查集在检查连通性方面非常好,一般用在求两点之间有没有路径等方面

其主要包括三个方面:

1.查找根结点(检查你所要找的点所属的根结点,对于一些联通的点来说任一节点都可以作为根结点,但对于这些联通的点来说根结点只有一个)

2.状态压缩(就是把联通的点的所有的根结点都定位同一个根结点)

3.将两个连通区域的点构建连通性。

查找根结点,状态压缩

	public static int findRoot(int pre[],int x)
	{
		int temp = x;
		while(pre[temp]!=temp)//找根
		{
			temp = pre[temp];
		}
		//状态压缩
		int j = x;
		while(pre[j]!=temp)
		{//追本溯源凡是x上级的都把他们的根赋予他们
			int pr = pre[j];
			pre[j] = temp;
			j = pre[j];
		}
		return temp;
	}
构建连通性

//并查集中将两个阵营的团队结合
	public static void mix(int pre[],int x,int y)
	{
		int a = findRoot(pre,x);
		int b = findRoot(pre,y);
		if(a!=b)
			pre[a] = b;//赋有将共同的boss
	}
2005年浙江大学计算机及软件工程研究生机试真题

下面是完整的实现代码

import java.util.Scanner;

public class unionFind1012Jo {
	
//并查集,首先是找到其中的根结点,再进一步进行状态压缩
	public static int findRoot(int pre[],int x)
	{
		int temp = x;
		while(pre[temp]!=temp)//找根
		{
			temp = pre[temp];
		}
		//状态压缩
		int j = x;
		while(pre[j]!=temp)
		{//追本溯源凡是x上级的都把他们的根赋予他们
			int pr = pre[j];
			pre[j] = temp;
			j = pre[j];
		}
		return temp;
	}
//并查集中将两个阵营的团队结合
	public static void mix(int pre[],int x,int y)
	{
		int a = findRoot(pre,x);
		int b = findRoot(pre,y);
		if(a!=b)
			pre[a] = b;//赋有将共同的boss
	}
	public static void main(String[] args) 
	{
		// TODO Auto-generated method stub
		int[] pre = new int[1000];
		
		Scanner in = new Scanner(System.in);
		int count = 0;
		while((count = in.nextInt())!=0)
		{
			for(int i = 1;i< 1000;i++)
			{
				pre[i] = i;
			}
	    int num = count-1;
		int i = in.nextInt();
		
			while(i-->0)
			{
				int a = in.nextInt();
				int b = in.nextInt();
				if(findRoot(pre,a)!=findRoot(pre,b))
				{
					mix(pre,a,b);
					num--;
				}
			}
			System.out.println(num);
		}
	}

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值