首页 > 其他分享 >The Third Letter带权并查集

The Third Letter带权并查集

时间:2023-07-27 09:46:05浏览次数:37  
标签:return ff int 边权 查集 Codeforces 带权 Letter 节点

Problem - 1850H - Codeforces

题意是给你a,b,c说明a在b后面c个单位(c<0就是在左边),每个位置只能有一个数,一共有n个位置,告诉你m个关系,问是否符合条件

我们可以设置d[x]表示x到它的最早的父节点的距离,然后如果两个数父节点一样,那么c!=d[a]-d[b]时就说明不符合条件

那么对于并查集的合并是怎么操作的呢?

如图,如果输入的是b,y,s说明b在y的右边s距离,我们只需要把a放到y右边(s-d[b])距离即可

需要注意的是,在更新边权的时候,要等它的父节点更新边权完成后再加上它父节点的边权

查看代码

// Problem: H. The Third Letter
// Contest: Codeforces - Codeforces Round 886 (Div. 4)
// URL: https://codeforces.com/problemset/problem/1850/H
// Memory Limit: 256 MB
// Time Limit: 2000 ms

#pragma GCC optimize(2)
#include<iostream>
#define int long long
using namespace std;
int f[200005],d[200005];
int ff(int x)
{
	if(x==f[x])return x;
	int tmp=f[x],cc=ff(f[x]);
	d[x]+=d[tmp];//等父节点更新完边权后再更新该节点边权
	f[x]=cc;
	return cc;
}
void solve()
{
	int n,m;
	cin>>n>>m;
	bool s=1;
	for(int i=1;i<=n;i++)f[i]=i,d[i]=0;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		int a=ff(x),b=ff(y);
		if(a!=b)
		{
			d[a]=z-d[x];
			f[a]=y;
		}
		else
		{
			if(z!=d[x]-d[y])
			{
				s=0;
			}
		}
	}
	if(!s)
	{
		cout<<"NO\n";
	}
	else cout<<"YES\n";
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)solve();
	return 0;
}

标签:return,ff,int,边权,查集,Codeforces,带权,Letter,节点
From: https://www.cnblogs.com/qbning/p/17584094.html

相关文章

  • 算法刷题笔记--并查集的运用
    1、题目描述:一个城市中有两个犯罪团伙A和B,你需要帮助警察判断任意两起案件是否是同一个犯罪团伙所为,警察所获得的信息是有限的。假设现在有N起案件(N<=100000),编号为1到N,每起案件由团伙A或团伙B所为。你将按时间顺序获得M条信息(M<=100000),这些信息分为两类:D[a][b]其中[a]和[b]表示两......
  • 算法学习--并查集相关知识及例题
    一、并查集的定义二、基本操作1、初始化一开始,每个元素都是独立的集合#include<iostream>usingnamespacestd;constintmaxN=1000;intfather[maxN];intmain(){for(inti=1;i<=maxN;i++){father[i]=i;}return0;}2、查找递推版本://返......
  • 【学习笔记】并查集
    先来看百度百科上的定义:并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。并查集是一种树型的数据结构,用于处理一些不相交集合(disjointsets)的合......
  • 并查集
    在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内竞赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据......
  • 擒贼先擒王(并查集)
    擒贼先擒王(并查集)目录擒贼先擒王(并查集)题面题目概括思路AC代码和注释题面快过年了,犯罪分子也开始为年终奖奋斗了。晓哼的家乡出现了多次抢劫事件。由于强盗人数过于庞大,作案频繁,警方想查清楚到底有几个犯罪团伙实在太不容易了,不过警察叔叔还是搜集到了一些线索,需要咱们帮忙分析......
  • 并查集知识梳理
    并查集目录并查集并查集的定义并查集的思想朴素并查集的代码(1)初始化(2)查找(3)合并路径压缩(1)查找代码(2)路径压缩完整代码按秩合并思想实现(1)初始化(2)合并并查集的定义并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集通常包含两种操作:查找(Find):查询两个......
  • 并查集知识点梳理
    并查集目录并查集并查集的定义并查集的思想朴素并查集的代码(1)初始化(2)查找(3)合并路径压缩(1)查找代码(2)路径压缩完整代码按秩合并思想实现(1)初始化(2)合并并查集的定义并查集是一种树型的数据结构,用于处理一些不相交集合的合并及查询问题。并查集通常包含两种操作:查找(Find):查询两个......
  • LETTERS
    #include<bits/stdc++.h>usingnamespacestd;intr,s,t[200],ans;intdx[]={-1,0,1,0},dy[]={0,-1,0,1};chara[100][100];voiddfs(intx,inty,intcnt){ans=max(ans,cnt);for(inti=0;i<4;i++){intxx=x+dx[i];int......
  • java 检查集合长度
    Java检查集合长度的实现方法概述在Java开发中,我们经常需要检查集合的长度,以便判断集合中是否包含足够的元素或者进行其他操作。本文将介绍一个简单的方法来实现Java检查集合长度的功能。实现步骤下面是实现Java检查集合长度的步骤,可以用表格形式展示:步骤描述......
  • 并查集
    题目一共有$n$个数,编号是$1∼n$,最开始每个数各自在一个集合中。现在要进行$m$个操作,操作共有两种:Mab,将编号为$a$和$b$的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略这个操作;Qab,询问编号为$a$和$b$的两个数是否在同一个集合中;输入格式第一行输......