union-find算法

首先我们详细的说明以下问题:问题的输入是一列整数对,其中每个整数都表示一个某种类型的对象,一对整数p,q可以理解为“p和q是相连的”。我们假设“相连”是一种等价关系,这也就意味着它具有:
1.自反性:p和p是相连的。
2.对称性:如果p和q是相连的那么q和p也是相连的。
3.传递性:如果p和q是相连的且q和r是相连的,那么p和r也是相连的。
列子:输入的整数表示一个大型计算机网络中的计算机,而整数对则表示网络中的连接。通过输入的整数对找出我们需要在网络中连接的触点。
算法的API
public int count() //返回连通分量的数量
public void union(int p,int q); //连接p和q;
public boolean connected(int p,int q) //判断p和q是否是连通的
public int find(int p) //找出p的连通分量标识,改标识代表p所在的连接通路
第一种实现:我们用一个整形数组来标识每一个触点,如果两个触点是连通的就把他们的分量标记相等。
代码如下:

public class UF{
    private int count;
    private int[] a;
    //初始化,N代表触点总数,数组标识每一个触点,可连通的话值设为相等的,count为分量数,初始为N,连通一次减1
    public UF(int N){
        a = new int[N];
        count = N;
        for(int i=0;i<N;i++)
            a[i] = i;
    }
    //返回分量数量
    public int count(){
        return count;
    }
    //判断两个分量是否连通
    public boolean connected(int p,int q){
        return find(p)==find(q);
    }
    //获取所在分量标识
    public int find(int p){
        return a[p];
    }
    //连接两个分量
    public void union(int p,intq){
        int flagP = find(p);
        int flagQ = find(q);
        for(int i=0;i<a.leng;i++){
            if(a[i] == flagP)
                a[i] = flagQ;
        }
        count--;
    }
    //测试方法
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        //读入触点数量
        int N = scanner.nextInt();
        UF uf = new UF(N);
        while(scanner.hasNext()) {
            int p = scanner.nextInt();
            int q = scanner.nextInt();
            if(p == q)break;
            if(!uf.connected(p,q)) {
                uf.union(p,q);
                System.out.println(p+"-->"+q);//打印未连通的节点
            }
        }
        System.out.println("分量数量为:" + count);
    }
}   

这种实现方法每次连接两个触点需要遍历数组两次,比较费时,还有两种改善的方法,一种是通过树结构来实现,一种是通过加权的树来实现。这两种实现下次写,今天就先到这了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值