栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

这周的总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

这周的总结

这周主要学习了并查集的内容,学到了一些关于并查集的知识点及用法。

简单介绍一下并查集的用法:一共有两种,首先是合并,就是把一个根节点的所有子节点合并成一个集合,其次是查询,查询这个点属于哪个集合时,比较容易查询。简而言之,并查集就是可以高效的对元素进行分组并合并在一起,并且能快速的查询两个元素是否属于同一组。

知识点相当容易理解,但和题目结合在一起,就是有点困难了,平常是不会想到并查集这个解决方法的,但是学了就学会用这种方法去做,简单而又不难写。

关于并查集,也有优化方法,第一,就是按秩合并,就是合并时,不是那个并查集的结构类似于树状结构吗,合并时就看这两棵树的高度来看谁当父节点。第二个方法,就是路径压缩,将所有的子节点全部指向唯一的那个根节点,这样查询时就能更快的去查找了。

关于并查集的代码及其优化方法的代码就不用再写了,看一下我觉得比较典型的题目。

1.食物链 题意:

就是给出n个动物,k句话,在k句话中有真话和假话,话语中有两种操作,第一个是第几种和第几种是同类,另一个就是谁能吃谁,求其中假话的数量。

题解:

这是一个典型的运用并查集的例题,就是有天敌,同类,还有猎物。根据题意,x,y要么是同类要么是x吃y,x吃y,x是y的天敌,y是x的猎物,x的天敌是y的猎物。根据这个关系来写判断语句,而且根据这个确定数组的大小为3*n。

代码:
#include 
using namespace std;
int fa[150005];
int ans;
int find(int x)
{
    if (x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}

inline void merge(int x, int y)
{
    fa[find(x)] = find(y);
}
inline bool same(int x, int y)
{
    return find(x) == find(y);
}

int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= 3 * n; i++)
        fa[i] = i;
    for (int i = 1; i <= k; i++)
    {
        int c, x, y;
        cin >> c >> x >> y;
        if (x <= n && y <= n)
        {
            if (c == 1)
            {
                if (!same(x, y + n) && !same(x, y + 2 * n))
                {
                    merge(x, y);
                    merge(x + n, y + n);
                    merge(x + 2 * n, y + 2 * n);
                }
                else ans++;
            }
            else
            {
                if (x != y)
                {
                    if (!same(x, y) && !same(x, y + n))
                    {
                        merge(x + n, y);
                        merge(x + 2 * n, y + n);
                        merge(x, y + 2 * n);
                    }
                    else ans++;
                }
                else ans++;
            }
        }
        else ans++;
    }
    cout << ans << endl;
    return 0;
}

这个题非常典型,合并查找,用并查集做这个题真的非常方便。

2.The Suspects 题意:

就是有n个人,其中0是最初感染者,写出m个组,在一个组中都会被感染,求出最终感染的人数。

题解:

典型的并查集的题,和上面的题差不多,但比上面题略微简单一点,就是把同组的用所有成员并在一起,并查询与0同组的成员的数量。

代码:
#include 
using namespace std;
int fa[30005], sum[30005];
int find(int n)
{
	return fa[n] == n ? n : fa[n] = find(fa[n]);
}
void merge(int x, int y)
{
	int fx, fy;
	fx = find(x);
	fy = find(y);
	if (fx < fy)
	{
		fa[fy] = fx;
		sum[fx] += sum[fy];
	}
	if (fx > fy)
	{
		fa[fx] = fy;
		sum[fy] += sum[fx];
	}
}
int main()
{
	int n, m, k, a, b;
	while (cin >> n >> m)
	{
		for (int i = 0; i <= n; i++)
		{
			fa[i] = i;
			sum[i] = 1;
		}
		if (n == 0 && m == 0)break;
		for (int i = 0; i < m; i++)
		{
			cin >> k >> a;
			for (int j = 1; j < k; j++)
			{
				cin >> b;
				merge(a, b);
			}
		}
		cout << sum[0] << endl;
	}
	return 0;
}

这些题是比较典型的题,要经常回过头去看看,搜索的题又有点不怎么看得懂了,下周得回过头看看去,把下周的题目提前做完,去做搜索题去。都要加油!!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/869748.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号