1850H-The Third Letter

本文介绍了如何使用带权并查集解决士兵冲突问题,包括路径压缩函数、集合合并操作以及d数组的更新。作者通过实例展示了如何模拟并判断士兵位置是否冲突及合并集合的过程。
摘要由CSDN通过智能技术生成

题目链接:The Third Letter

本道题目就是带权并查集的模板题,但又好久没学忘了,再复习一遍。。。

路径压缩函数模板:

int root(int x){
	if(pre[x]!=x){
		int t=root(pre[x]);
		d[x]+=d[pre[x]];
		pre[x]=t;
	}
	return pre[x];
}

之后就模拟一下就行了,判断两个士兵是否在一个集合里面,如果在一个集合里面,那么就判断两个人的位置有没有冲突,如果不在一个集合里面,那么就把他们合并到一个集合里面。

 对于 d [ fx ] = d [ y ] - d [ x ] + z 的理解:

首先合并集合 pre [ fx ] = fy,那么路径也要合并,如图要求d[fx],那么就是求 ? 。

已知 d [ x ] + ? - d [ y ] = z 可以推导出该公式。

代码附上:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n,m;
int pre[N],d[N];

int root(int x){
	if(pre[x]!=x){
		int t=root(pre[x]);
		d[x]+=d[pre[x]];
		pre[x]=t;
	}
	return pre[x];
}

void init(){
	for(int i=1;i<=n;i++)pre[i]=i;
	for(int i=1;i<=n;i++)d[i]=0;
}

void solve(){
	cin>>n>>m;
	bool flag=true;
	init();

	while(m--){
		int x,y,z;cin>>x>>y>>z;
		int fx=root(x);
		int fy=root(y);
		if(fx!=fy){
			pre[fx]=fy;
			d[fx]=d[y]-d[x]+z;
		}
		else {
			if(d[x]-d[y]!=z){
				flag=false;
			}
		}
	}

	if(flag)cout<<"YES"<<"\n";
	else cout<<"NO"<<"\n";

}

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

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值