并查集系列(一)——Social network connectivity

来源:互联网 发布:基础软件服务经营范围 编辑:程序博客网 时间:2024/06/08 06:15

  course并查集的课后题之一,看完之后没有开始没有什么思路,也没找到什么答案,想了想写了一下,感觉受益挺多的

问题描述:

  Social network connectivity. Given a social network containing n members and a log file containing m timestamps at which times pairs of members formed friendships, design an algorithm to determine the earliest time at which all members are connected (i.e., every member is a friend of a friend of a friend … of a friend). Assume that the log file is sorted by timestamp and that friendship is an equivalence relation. The running time of your algorithm should be mlogn or better and use extra space proportional to n.
解题思路:
  首先对于这样的问题我们肯定要使用并查集来求解,题目求是在散列刚刚全部连通的时候的状态,所以我们需要判断什么时候刚刚连通。这时候会想到,全部连通时只会有一个父节点的存在所以,当我们做一次连接操作的时候做一次父节点的判断就行了,当使用weight quick union 的查询父节点操作的时间复杂度为logn,总的复杂度m(logn+1)=mlogn所以可解,下面附上java实现代码,希望可以帮助和我一样的初学者。

public class SocialNetworkConnectivity {    int[][] timestamp = new int[][]{{1, 2}, {1, 0}, {7, 8}, {6, 7}, {1, 5}, {4, 9}, {0, 3}, {0, 4}, {1, 6}, {5, 9}};    int[] point;    int count;    //计数器,表示剩余root节点的个数    int[] size;  //各个节点对应树的节点数量    //  初始化数组,都是散列的点,每个人是自己的father,初始化每个树的节点个数为1    public SocialNetworkConnectivity(int point) {        this.point = new int[point];        this.size = new int[point];        count = size.length;        for (int i = 0; i < this.point.length; i++) {            this.point[i] = i;        }        for (int i = 0; i < size.length; i++) {            size[i] = 1;        }    }    //   连接操作,将小树放在大树之下    public void union(int q, int p) {        int rootA = root(q);    //A的根节点        int rootB = root(p); //B的根节点        if (rootA == rootB) return;        if (size[rootA] < size[rootB]) {            point[rootA] = point[rootB];            size[rootB] += size[rootA];        } else {            point[rootB] = point[rootA];            size[rootA] += size[rootB];        }        count--;    }    //   返回当前给定元素的根节点    public int root(int i) {        while (point[i] != i) {            point[i] = point[point[i]];    //路径压缩            i = point[i];        }        return i;    }    public static void main(String[] args) {        SocialNetworkConnectivity so = new SocialNetworkConnectivity(10);        int count = 1;        while (true) {            Scanner scanner = new Scanner(System.in);            int q = scanner.nextInt();            int p = scanner.nextInt();            so.union(q, p);            if (so.count == 1) {                System.out.println("all points connected in log " + count);                break;            }            System.out.println(so.count);            count++;        }    }}

输出:

1 2
9
1 0
8
7 8
7
6 7
6
1 5
5
4 9
4
0 3
3
0 4
2
1 6
all points connected in log 9

0 0
原创粉丝点击