关于集合的思路

Description

输入一个无向图G,计算G的连通分支数。

Input

有多个无向图数据。每个无向描述的第1行是两个整数n和e,分别表示顶点数和边数。接着有e行,每行有2个整数a、b,分别是一条边的两个端点(起点和终点)。两个图之间空一行。

Output

对每个无向图,输出图中连通分支个数。

Sample Input

2 1 1 2 5 8 1 2 1 3 1 4 1 5 2 3 2 4 3 4 4 5

Sample Output

1 1

先看这个,嗯,说白了就是集合起来神马的,我百度了一下,草,是BFS耶

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxlen 1100
using namespace std;
bool maps[maxlen][maxlen];
int visited[maxlen];
int n,m;
void dfs(int i)
{
    if(visited[i])
        return ;
     visited[i]=true;
     for(int j=1;j<=n;++j)
     {
         if(maps[i][j]==true&&!visited[j])
         {
             dfs(j);
         }
    }
 }
 int main ()
{
     int a,b;
     while(scanf("%d%d",&n,&m)!=EOF)
     {
         for(int i=0;i<=n;++i)
         for(int j=0;j<=n;++j)
         {
             if(i==j)
                 maps[i][j]=1;
             else
                maps[i][j]=0;
        }
         for(int i=0;i<m;++i)
        {
             scanf("%d%d",&a,&b);
             maps[a][b]=maps[b][a]=true;
         }
         memset(visited,0,sizeof(visited));
         int ans=0;
         for(int i=1;i<=n;++i)
         {
             if(!visited[i])
             {
                 dfs(i);
                 ans++;
             }
         }
       printf("%d\n",ans);
     }
 }

  然后再看下一道

Description

超级无敌张小豪是A国的一名勇士,A国的勇士都要靠获得能量变得更强,在A国勇士获得能量只有唯一的一种途径就是膜拜宙斯神——周尼玛(桑!!!)。要膜拜周尼玛就要去到遥远的大日国那里有好多好多周尼玛(桑!!!)。但是周尼玛(桑!!!)是一种群居动物,一队周尼玛(桑!!!)中都有且只有一个领袖叫周尼玛你妹(桑!!!)超级无敌张小豪勇士必须拿着一炷香到周尼玛你妹(桑!!!)面前膜拜三下即可获得一点能量。

膜拜必须遵循一些规则:

对于一个周尼玛你妹(桑!!!)只能膜拜一次;

不能膜拜周尼玛(桑!!!);

一次膜拜用一炷香且一炷香只能膜拜一次;

现在问题出现了,小豪准备启程去大日国,在走之前小豪要准备买香但是小豪不知道大日国一共有几队周尼玛(桑!!!),小豪既想每个周尼玛你妹(桑!!!)都膜拜到,又想带过去的香能用完不浪费。于是小豪打听小道消息搞过来了一张周尼玛(桑!!!)家族谱。

家族谱上有若干对数字

eg:1 2

2 4

表示:周尼玛1号和周尼玛2号是一队的

周尼玛2号和周尼玛4号是一队的

若谱上告诉你周尼玛x号和周尼玛y号是一队的周尼玛y号和周尼玛z号是一队的

那也就代表了周尼玛x号和周尼玛z号是一队的了。

Input

The input starts with an integer T(1<=T<=10) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N<= 30000,1<=M<= 500000). N indicates the number of周尼玛, the 周尼玛 are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means 周尼玛 A号 and 周尼玛 B号 in the same team. There will be a blank line between two cases.

Output

For each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.

Sample Input

2 5 3 1 2 2 3 4 5 5 1 2 5

Sample Output

2 4

先让我说一句,周尼玛尼玛个大鬼头!!!我都被尼玛洗脑有木有?!

嗯,感觉和上面一样.....还是用BFS,但是看看1<=N<= 30000,1<=M<= 500000.....一股不祥的预感.....果然超时了.....

看了一下网上解法,原来是并查集.....

#include <iostream>
using namespace std;

const int N=30000;
int flag[N];

int Find_Set(int x)
{
    if(x!=flag[x])
    {
        flag[x]=Find_Set(flag[x]);
    }
    return flag[x];
}

int main()
{
    int t,m,n,i,j,a,b,A,B,num;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(i=1;i<=n;i++) flag[i]=i;
        num=n;
        for(i=1;i<=m;i++)
        {
            cin>>A>>B;
            a=Find_Set(A);
            b=Find_Set(B);
            if(a>b)
            {
                flag[a]=b;
                num--;
            }
            else if(a<b)
            {
                flag[b]=a;
                num--;
            }
        }
        cout<<num<<endl;
    }
    return 0;
}

  然后再倒过来再考虑一下能否用并查集搞定无向图的连通支路?

#include <iostream>
#include <string.h>
using namespace std;

const int N=30000;
int flag[N];

int Find_Set(int x)
{
    if(x!=flag[x])
    {
        flag[x]=Find_Set(flag[x]);
    }
    return flag[x];
}

int main()
{
    int t,m,n,i,j,a,b,A,B,num;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
    	memset(flag,0,sizeof(flag));
    	for(i=1;i<=n;i++) flag[i]=i;
        num=n;
        for(i=1;i<=m;i++)
        {
            cin>>A>>B;
            a=Find_Set(A);
            b=Find_Set(B);
            if(a>b)
            {
                flag[a]=b;
                num--;
            }
            else if(a<b)
            {
                flag[b]=a;
                num--;
            }
        }
        cout<<num<<endl;

	}
	return 0;
}

  就这样搞定了.....突然觉得我真不是搞ACM的材料.....妈蛋

关于集合的思路,布布扣,bubuko.com

时间: 2024-12-21 11:36:21

关于集合的思路的相关文章

集合学习思路

集合的分类 集合按照其存储结构可以分为两大类: 单列集合java.util.Collection 双列集合java.util.Map 学习集合的目标 会使用集合存储数据 会遍历集合,把数据取出来 掌握每种集合的特性 集合学习的方式 学习顶层:学习顶层接口/抽象类中的共性方法,所有的子类都可以使用 使用底层:需要使用底层的子类创建对象使用 原文地址:https://www.cnblogs.com/wurengen/p/10860108.html

获取一个想要的指定文件的集合,获取文件夹下(包含子目录的所有.java的文件对象,并存储到集合中)

import java.io.File; import java.io.FileFilter; import java.io.ObjectInputStream.GetField; import java.util.ArrayList; import java.util.List; public class huoquwenjian { /*获取一个想要的指定文件的集合,获取文件夹下(包含子目录的所有.java的文件对象,并存储到集合中) * 思路: * 1,既然包含子目录,就需要递归. * 2

集合与IO的一个小联系

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.ios培训..Net培训</a>.期待与您交流!------ 集合与IO的一个小联系: Properties 是集合中的一员,他是hashtable的子类也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串 该类最主要的操作是用于操作配置文件的这里只简单说一下它和IO技术的联系: 查阅API

黑马程序员-java基础-集合Map

-----Java培训.Android培训.iOS培训..Net培训.期待与您交流! Map<K,V> Map<K,V>:Map存储的是键值对形式的元素,它的每一个元素,都是由键和值两个元素组成,键是不能有重复的,值是可以重复的,每一个键唯一指向一个值. Map体系 Map ——|hashtable: 底层是哈希表数据结构,不可以存入null键null值.该集合是线程同步的.效率低,已被HashMap替代 ——|HashMap: 底层是哈希表数据结构,允许使用 null 值和 nu

Collection单列集合 Map双列集合

Map集合:该集合存储键值对,一对一对往里存.而且要保证键的唯一性. 1.添加 put(K key, V value) putAll(Map<? extends K,? extends V> m) 2.删除 clear() remove(Object key) 3.判断 containsKey(Object key) containsValue(Object value) isEmpty() 4.获取 get(Object key) :获取值 size() values() entrySet(

SQL 集合(笔记)

——SQL是关于集合的 oracle是关系型数据,其中的数据表都是有一定规律的数据的一个个集合,所以在使用SQL时,如果能按照集合的思路来进行时会节省很多效率,也鞥让语句更加的清晰明了. 1.四个集合运算符 1)union 返回不重复的数据行: 2)union all 返回所有的数据行(包括重复的): 3)minus 返回第一个输入查询存在,其他查询不存在的数据行: 4)intersect 返回所有数据查询中都存在的数据行. 注:除union all 以外的集合运算都需要对结果进行排序/取唯一值

黑马程序员——黑马基础——Map,集合框架工具类Conlections和Arrays

黑马程序员--黑马基础--Map,集合框架工具类Conlections和Arrays ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一,Map集合 Map<K,V>集合是一个接口,和List集合及Set集合不同的是,它是双列集合,并且可以给对象加上名字,即键(Key). 特点: 1)该集合存储键值对,一对一对往里存 2)要保证键的唯一性. Map集合的子类 Map |--Hashtable:底层是哈希表数据结构,不可以存入null键nu

快速排序--QuickSort,看完五分彩开奖网平台搭建自己就能写出来的快排思路推演

快速五分彩开奖网平台搭建论坛:haozbbs.com Q1446595067排序(QuickSort)介绍首先发明者竟然敢给自己发明的算法叫做QuickSort,这个名字闪不闪亮?好比别的武功叫做六脉神剑.降龙十八掌,我这个叫做"天下无敌神功".别的排序算法都是按照特点来起的,你这个不是应该叫分块递归排序法吗?或者和希尔一样,叫做霍尔排序也可以啊,这么高调是要干啥啊?我给了他一次机会,特意去查了一下,这个名字并不是江湖朋友抬爱给的,就是发明者自己起的,社会社会...不过看完这篇博客,理

[hdoj]3006//位运算+枚举

题意:给出n个集合,问这些集合能组合成几种不同的集合. 思路:枚举+状态压缩.由于1<=m<=14,所以最多有2^14=16 384种状态,每种状态可以存在一个int中.枚举所有的状态,运用位运算,判断能否由这n个集合组成. #include<iostream> using namespace std; int main(){ int n, m, k, w, i, j; int ans, val[105]; while(cin >> n >> m){ for