IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 食物链 拓展域 边带权 -> 正文阅读

[数据结构与算法]食物链 拓展域 边带权

首先我们知道并查集可以维护集合间的关系,当关系只有一种的时候是比较好维护的。但是当关系较多的时候拓展域在我看来是比边带权好想一些的,因为边带权表示多种关系的的话势必要利用每个节点到根结点的距离来做文章。
例如下题:
食物链,题目链接
边带权:
我们把所有有关系的的节点都放到一个集合内,并用每个节点到其根结点的距离来表示其与根节点的的关系,而根据每个节点与根节点的关系我们就可以得知每个节点之间的关系,设根节点为A,假设B到根节点的距离为1,并表示B被A吃。再假设C到根节点的距离为2,并表示A被C吃,那么根据题意可以得出C被B吃。
所以三个一个循环我们就可以通过(d[i]%3)来判断i与其根节点之间的关系,继而推出每个节点之间的关系。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int p[N];
int d[N];//d[i]代表i到该根节点的距离 
int find(int x) {
	if (x == p[x])return p[x];
	else {
		int t = find(p[x]);
		d[x] += d[p[x]];
		p[x] = t;
		return p[x];
	}
}
int main() {
	int n, k, c, x, y, res = 0;
	cin >> n >> k;
	for (int i = 1; i <= n; i++)p[i] = i;
	for (int i = 1; i <= k; i++) {
		cin >> c >> x >> y;
		if (x > n || y > n)res++;
		else {
			int dx = find(x), dy = find(y);
			if (c == 1) {
				if (dx == dy && (d[x] - d[y]) % 3)res++;
				else  if (dx != dy) {
					p[dx] = dy;
					d[dx] = d[y] - d[x];//(d[x]+d[dx]-d[y] )%3==0,
					//所以d[dx]=d[x]-d[y]
				}
			} else {
				if (dx == dy && (d[x] - d[y] - 1) % 3)res++; //(d[x]-d[y])%3有可能是-2,
				//也有可能是1而这两种情况是相同的都是x<-y。画画图就知道了。
				else if (dx != dy) {
					p[dx] = dy;
					d[dx] = d[y] + 1 - d[x] ;//同理。
				}
			}
		}

	}
	cout << res;
	return 0;
}

拓展域:
假设有N个元素构成一个集合,而每个元素之间有多种关系。假设A,B,C三个元素,B是A的食物,C是A的天敌自然A是C的食物,但是C也是B的食物。。。。就很乱,但是我们从中提取出三种关系同类,食物,和天敌。
1~n来表示自身:
n+1~2n来表示自己的食物;
2
n+1~3*n来表示自己的天敌;
那么当a与b是同类的时候,a的天敌和b的天敌是同类,a的食物和b的食物也是同类。
当a吃b的时候,a的食物和b是同类,a的天敌和b的食物是同类,b的天敌和a是同类;
类比上一个代码这个还是比较好写的,但是这个空间复杂度较高,理清楚元素之间的关系才是难点。

#include<bits/stdc++.h>
using namespace std;
const int N= 3e5+10;
int p[N];
int get(int x)
{
	if(x==p[x])return p[x];
	return p[x]=get(p[x]);
}
void merge(int x,int y)
{
	int dx=get(x);
	int dy=get(y);
	if(dx!=dy)
	{
		p[dx]=p[dy];
	}
}
int main()
{
	int n,k,res=0;
	cin>>n>>k;
	for(int i=1;i<=3*n;i++)p[i]=i;
	for(int i=1;i<=k;i++)
	{
		int c,a,b;
		cin>>c>>a>>b;
		if(a<1||a>n||b<1||b>n)res++;
		else if(a==b&&c==2) res++;
		else
		{
			if(c==1)
			{
				if(get(a)==get(b+n)||get(a+n)==get(b))res++;
				else
				{
					merge(a,b);
					merge(a+n,b+n);
					merge(a+2*n,b+2*n);
				}
			}
			else {
				if(get(a)==get(b)||get(a)==get(b+n))res++;
				else
				{
					merge(a+n,b);
					merge(a+2*n,b+n);
					merge(a,b+2*n);
				}
			}
		}
	}
	cout<<res;
	return 0;
} 
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:44:27  更:2022-05-05 11:44:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:17:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码