【九度】题目1526:朋友圈

原创 2013年12月03日 21:48:43

题目1526:朋友圈

题目描述:
      假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。
      假如:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。
输入:
      输入包含多个测试用例,每个测试用例的第一行包含两个正整数 n、m,1=<n,m<=100000。接下来有m行,每行分别输入两个人的编号f,t(1=<f,t<=n),表示f和t是好友。 当n为0时,输入结束,该用例不被处理。
输出:
      对应每个测试用例,输出在这n个人里一共有多少个朋友圈。
样例输入:
5 3
1 2
2 3
4 5
3 3
1 2
1 3
2 3
0
样例输出:
2
1
【解题思路】
这应该是并查集最简单的应用了,求集合个数。
基本思路:
1、每次输入节点的时候,就合并。
2、依次查找每个节点的父节点。
3、放在set中,set.size()即为朋友圈的个数。
并查集的应用很多,在很多时候效率比prim以及Dijkstra算法效率要高。
后面会有一些题两者都可以做出。我会给出比较。
C++ AC

#include <stdio.h>
const int maxn = 100002;
int parent[maxn];
int n;
int m;
int i;
 
int findParent(int f) {  
    while(parent[f] != f){
        f = parent[f];
    }
    return f;
}  
 
void unionTwo(int f, int t) {  
             
    int a = findParent(f);  
    int b = findParent(t);  
    if (a == b) return;   
    if (a > b) {     
        parent[a] = b;     
    } else {  
        parent[b] = a;   
    }  
}  
 
 
int main(){
    while(scanf("%d",&n) != EOF){
        if(n == 0){
          break;
        }
        scanf("%d",&m);
        if(n == 1){
            printf("1\n");
        }else{
            for(i = 1; i < n+1; i++){
                parent[i] = i;
            }
            for(i = 0 ; i < m ; i++){
                int a, b;
                scanf("%d%d",&a,&b);
                unionTwo(a,b);
            }
            for (i = 1; i < n+1; i++) {  
                parent[i] = findParent(i);  
            }
            int num = 0;
            for(i = 1; i < n+1; i++){
                if(parent[i] == i){
                    num ++;
                }
            }
            printf("%d\n",num);
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1526
    User: wangzhenqing
    Language: C++
    Result: Accepted
    Time:210 ms
    Memory:1412 kb
****************************************************************/

Java AC

import java.io.StreamTokenizer;
import java.util.HashSet;
import java.util.Set;
 
public class Main {
     /*
     * 1526
     */
    public static void main(String[] args) throws Exception{
        StreamTokenizer st = new StreamTokenizer(System.in);
        while (st.nextToken() != StreamTokenizer.TT_EOF) {
            int n = (int) st.nval;
            if (n == 0) {
                break;
            }
            if (n == 1) {
                System.out.println(1);
            }else {
                int []parent = new int[n+1];
                for (int i = 1; i <= n; i++) {
                    parent[i] = i;
                }
                st.nextToken() ;
                int m = (int) st.nval;
                for (int i = 0; i < m; i++) {
                    st.nextToken() ;
                    int f = (int) st.nval;
                    st.nextToken() ;
                    int t = (int) st.nval;
                    union(f ,t , parent );
                }
                 
                for (int i = 1; i < n+1; i++) {
                    parent[i] = findParent(i, parent);
                }
                Set<Integer> numSet = new HashSet<Integer>();
                for (int i = 1; i < n+1; i++) {
                    numSet.add(parent[i]);
                }
                System.out.println( numSet.size());
            }
        }
    }
  
    private static void union(int f, int t, int[] parent ) {
          
        int a = findParent(f , parent);
        int b = findParent(t , parent);
        if (a == b) return; 
        if (a > b) {   
            parent[a] = b;   
         } else {
            parent[b] = a; 
         }
    }
  
    private static int findParent(int f, int[] parent) {
        if (parent[f] == f) {
            return f;
        }
        return findParent(parent[f],parent );
    }
}   
/**************************************************************
    Problem: 1526
    User: wzqwsrf
    Language: Java
    Result: Accepted
    Time:970 ms
    Memory:42400 kb
****************************************************************/

其实在查找父节点的时候,不应该用递归,
直接用while效率比较高。
这在一些代码中有体现。
将parent[]声明为公共属性。
将以下这个方法修改为:
修改前:

private static int findParent(int f, int[] parent) {
    if (parent[f] == f) {
        return f;
    }
    return findParent(parent[f],parent );
}
修改后:

private static int findParent(int f) {
    while (parent[f] != f) {
        f = parent[f];
    }
    return f;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

九度题目1526:朋友圈

题目1526:朋友圈 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:934 解决:278 题目描述: 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间...

九度OJ题目 1526 朋友圈 并查集

题目描述: 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。 假如:n ...

<九度 OJ>题目1526:朋友圈

题目描述: 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。 Total...

九度Online Judge_1526: 朋友圈

题目描述:假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。 假如:n = 5...

九度 1526:朋友圈

刚学的并查集, 真是好用 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:810 解决:239 题目描述: 假如已知有n个...

【九度OJ】:1526 并查集 朋友圈问题

假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友…),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。 假如:n = 5 , m = ...

九度OJ 朋友圈 -- 并查集

题目地址:http://ac.jobdu.com/problem.php?pid=1526 题目描述: 假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好...
  • JDPlus
  • JDPlus
  • 2014-02-19 17:25
  • 2251

九度-简单题 题目1156:谁是你的潜在朋友

#include #include #include using namespace std; int main(){ int n,m; int a[200]; while(c...

九度题目1156:谁是你的潜在朋友

原题链接:http://ac.jobdu.com/problem.php?pid=1156 题目描述:     “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多...

【学习笔记】〖九度OJ〗题目1156:谁是你的潜在朋友

题目1156:谁是你的潜在朋友 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2594 解决:1214 题目描述:     “臭味...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)