More is better(MST)(求无向图中最大集合元素个数)

More is better

Time Limit:1000MS     Memory Limit:102400KB     64bit IO Format:%I64d & %I64u

Submit Status Practice HDU 1856

Description

Mr Wang wants some boys to help him with a project. Because the project is rather complex, the more boys come, the better it will be. Of course there are certain requirements.

Mr Wang selected a room big enough to hold the boys. The boy who are not been chosen has to leave the room immediately. There are 10000000 boys in the room numbered from 1 to 10000000 at the very beginning. After Mr Wang‘s selection any two of them who are still in this room should be friends (direct or indirect), or there is only one boy left. Given all the direct friend-pairs, you should decide the best way.

Input

The first line of the input contains an integer n (0 ≤ n ≤ 100 000) - the number of direct friend-pairs. The following n lines each contains a pair of numbers A and B separated by a single space that suggests A and B are direct friends. (A ≠ B, 1 ≤ A, B ≤ 10000000)

Output

The output in one line contains exactly one integer equals to the maximum number of boys Mr Wang may keep.

Sample Input

4
1 2
3 4
5 6
1 6
4
1 2
3 4
5 6
7 8

Sample Output

4
2

Hint

 A and B are friends(direct or indirect), B and C are friends(direct or indirect), then A and C are also friends(indirect). In the first sample {1,2,5,6} is the result. In the second sample {1,2},{3,4},{5,6},{7,8} are four kinds of answers.
         

#include<stdio.h>
#include<algorithm>
using namespace std;
int p[10000010] , rk[10000010] , maxn ;
int m ;

void init ()
{
    for (int i = 0 ; i <= 10000010 ; i++) {
        p[i] = i ;
        rk[i] = 1 ;
    }
    maxn = 0 ;
}

int find (int x)
{
    return x == p[x] ? x : p[x] = find (p[x]) ;
}

void Union (int x , int y)
{
    p[x] = y ;
    rk[y] += rk[x] ;
    maxn = max (maxn , rk[y]) ;
    rk[x] = 0 ;
}

int main ()
{
        //freopen ("a.txt" , "r" , stdin ) ;
        int x , y ;
        while (~ scanf ("%d" , &m) ) {
            init () ;
            for (int i = 0 ; i < m ; i++ ) {
                scanf ("%d%d" , &x , &y ) ;
                x = find (x) ;
                y = find (y) ;
                if (x != y)
                    Union ( x , y ) ;
            }
            if (maxn )
                printf ("%d\n" , maxn ) ;
            else
                printf ("1\n") ;
        }
        return 0 ;
}
时间: 2024-10-18 05:49:53

More is better(MST)(求无向图中最大集合元素个数)的相关文章

算法题:求数组中最小的k个数

说明:本文仅供学习交流,转载请标明出处,欢迎转载! 题目:输入n个整数,找出其中最小的k个数. <剑指offer>给出了两种实现算法: 算法1:采用Partition+递归法,该算法可以说是快速排序和二分查找的有机结合.算法的时间复杂度为O(n),缺点在于在修改Partition的过程中会修改原数组的值. 算法2:采用top-k算法.如果要找最小的K个数,我们才用一个含有K个值的大顶堆:如果要找最大的K个数,我们采用小顶堆.该算法的时间复杂度为O(nlogK),是一种比较好的算法,启发于堆排序

用C随机产生的正整数存到数组中,并求数组中的所有元素最大值、最小值、平均值以及各元素之和,及第二大值。

用 C 求一组随机数的第二大值,不能通过对整体排序求得 1 随机产生20个[10 , 50]的正整数存到数组中,并求数组中的所有元素最大值.最小值.平均值以及各元素之和,及第二大值.        int a[20];    int sum = 0; //存储数组元素的和    //为数组赋值    printf("数组中的元素为:\n ");    for (int i = 0; i < 20; i ++) {        a[i] = arc4random() % 41 +

2015华为机试——求n!中含有0的个数

题目描述: 求n!中含有0的个数,例如1!= 1 含有0个0,5! = 120 含有1个0,10! = 3628800 含有2个0 解题思路: 这题之前在leetcode中做过,如果先对n进行阶乘运算,然后%10求0的个数.但是n!很有可能溢出,所以需要找到它的等效方法,0的个数即为10的个数,即为5于2的个数,显然在n!中,2的个数要大于5的个数,因此只要算出n范围内有多少个5就OK 代码如下: public static int getZeroCount(int n) { /*在这里实现功能

求二叉树中叶子节点的个数

求二叉树中叶子节点的个数 面试题二叉树 题目描述 求二叉树中叶子节点的个数. 叶子节点的定义:如果一个节点既没有左孩子,也没有右孩子,则该节点为叶子节点. 示例: 3 / 9 20 / 15 7 在这个二叉树中,叶子节点有 9,15,7,所以返回 3. Java 实现 class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } class Solution { public int

萌新笔记——Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)

最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对"基数"以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了"HyperLogLog",从而引出了Cardinality Estimation算法,以及学习它时参考的一些文章: http://blog.codinglabs.org/articles/algorithms-for-cardinality-estimation-part-i.html 从文章上看来,基数是指一个

并查集的应用之求解无向图中的连接分量个数

一,介绍 本文使用数据结构:并查集 来实现 求解无向图的连通分量个数. 无向图的连通分量就是:无向图的一个极大连通子图,在极大连通子图中任意两个顶点之间一定存在一条路径.对于连通的无向图而言,只有一个连通分量. 二,构造一个简单的无向图 这里仅演示求解无向图的连通分量,因此需要先构造一个无向图.图由顶点和边组成,并采用图的邻接表形式存储.顶点类和边类的定义如下: 1 private class Vertex{ 2 private Integer vertexLabel; 3 private Li

求水洼的问题(或者是说求图中连通子图的个数)----深度优先算法

遇到这个题的时候,不太容易快速的想到思路:可能会比较容易想到使用递归的思想:但是具体怎么写呢?其实这个题就相当于是图论中的求连通图,很容易应该想到的是深度优先搜索或者是广度优先搜索:我们就用深度优先算法来求这个题目:直接求有几个区域不好求,那么我们换个思路来求,这种题就是这样,直接求不好求,但是当我们转换一下思路之后就豁然开朗: 我们遍历所有的点,当遇到有水的点时,就将它周围的(八个方向)所有的水点都消除:所以在主遍历for循环中遇到几个水点就是有几个水洼: /*****************

随机产生20个[10 , 50]的正整数存到数组中,并求数组中的所有元素最大值、最小值、平均值以及各元素之和,及第二大值。

int a[20] = {0};//定义一个长度为20的数组a int max = 0;//用来存储数组a中所有元素的最大值 int min = 0;//用来存储数组a中所有元素的最小值 int sum = 0;//用来存储数组a各元素的和 float aver = 0.0;//用来存储数组a中所有元素的平均值 int secondMax = 0;//用来存储数组a的第二大值,第二大值 为 不同于最大值的剩余元素的最大值 for (int i = 0; i < 20; i++) {//用来循环获

O(1)时间求栈中最小(大)元素

问题:对stack进行扩展,完成正常的push,pop操作,新增访问最小(大)元素的接口min(max),使得push,pop,Min的时间复杂度都是O(1). 难点在于怎么维持stack的最小(大)值,一切排序和查找都不可能实现O(1)的时间复杂度找到最小值. 思路:如下图所示,以空间换取时间.通过增加一个最小值栈来存储上一个最小值,以维持目前的最小值. 1.  入栈的元素比当前的min小:如当min=3时,元素2入栈,则将当前最小值3push进最小值栈,min变为2. 2.  出栈的元素为当